﻿using CCWin.Win32.Const;
using csDmc1380;
using HalconDotNet;
using HVisionCH;
using Newtonsoft.Json;

//using Microsoft.Win32;
using Sszn;
using Sunny.UI.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Media;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using WindowsFormsApp1.Forms;
using WindowsFormsApp2.Properties;
using WindowsFormsApp2.工具函数;
using WindowsFormsApp2.接口类;
using WindowsFormsApp2.类;
using YJYpublicClass;
using static WindowsFormsApp2.接口类.AligningControl;
using Color = System.Drawing.Color;


namespace WindowsFormsApp2
{
    public partial class MainForm : Form
    {


        public MainForm()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;   //允许跨线程访问不报错，参数加载完后关闭
        }

        //注册6个移动轴
        Wheel Wheel1 = new Wheel(1, 1, 2, 19, 18, 17, 270);
        Wheel Wheel2 = new Wheel(2, 3, 4, 22, 21, 20, 239);
        Wheel Wheel3 = new Wheel(3, 5, 6, 25, 24, 23, 240);
        Wheel Wheel4 = new Wheel(4, 7, 8, 28, 27, 26, 275);
        Wheel JackRightLeft = new Wheel(5, 9, 20, 29, 0, 0, 100, -100, 100);
        Wheel JackUpDown = new Wheel(6, 11, 12, 30, 0, 0, 50, -50, 50);
        Wheel[] wheels = new Wheel[4];
        Wheel[] Jacks = new Wheel[2];
        //参数对象
        AxisSettings axisSettings = new AxisSettings();
        string SettingPath;



        Frm_Welcome welcomefrom = new Frm_Welcome();

        Boolean InitOK = false; //初始化状态标志
        int ExitSta = 0;  //程序退出标志
        PLCconfig PLCConfig = null;
        DWL_Config LightConfig = null;

        HDPL_24W350_Config HD_LightConfig = null;
        //图像处理1
        HDevProgram HalconProgram2 = null;
        HDevProcedure hproduce = null;
        public HDevProcedureCall ProcCall = null;
        public HDevProcedure hproduce2 = null;
        public HDevProcedureCall ProcCall2 = null;

        List<HDevProcedure> hproduces2 = new List<HDevProcedure>() { null, null, null, null, null, null };
        List<HDevProcedureCall> ProcCalls2 = new List<HDevProcedureCall>() { null, null, null, null, null, null };
        List<Label> ResultLabels = new List<Label>();
        List<HObject> S1Images = new List<HObject>();
        List<HObject> S2Images = new List<HObject>();
        List<HWindowControl> hWindowControls = new List<HWindowControl>();
        List<string> Results = new List<string>();
        List<Label> NGLabels = new List<Label>();
        List<string> SNNums = new List<string>();
        List<ScanData> qQlist = new List<ScanData>();

        //MES
        WebReference.WebService webService = new WebReference.WebService();



        //QQ qQ = new QQ();
        Hashtable SNtoDeviNum = new Hashtable();
        Dictionary<string, int> SNtoSumNum = new Dictionary<string, int>();
        bool RunFlag = false;
        bool S2RunFlag = false;


        public HObject tempoutobj = new HObject();
        public HTuple tempoutPras = new HTuple();

        public StationPramas stationPramas = new StationPramas();

        public static MainForm form1 = null;
        enum gongwei
        {
            面阵 = 0, 线扫, 双目
        }

        string Solutionpath = null;
        Image finePic = null;
        Image abnormalPic = null;


        //软件软急停信号
        bool SoftEmergencyFlag = false;
        bool ClearEmrgency = false;
        private void Form1_Load(object sender, EventArgs e)
        {

            form1 = this;
            //先把屏幕关掉
            this.Visible = false;
            this.Opacity = 0;

            //相机消息显示事件注册执行函数，在初始化之前
            CamControl7400_2.ShowInfo1 += RunLogMessage;
            CamControl7900.ShowInfo1 += RunLogMessage;

            //开线程，初始化
            Task t1 = new Task(AppINIT);
            t1.Start();

            //显示 加载界面
            welcomefrom.ShowDialog();//?
            welcomefrom.Dispose();

            //控制窗口
            this.Visible = true;
            this.Opacity = 1;
            this.WindowState = FormWindowState.Maximized;
            窗口调整();

            //激活实时显示
            显示_tick.Enabled = true;
            //
            //外设.Camera.m_Window = this.hWindowControl1.HalconWindow;
            //加载曝光参数
            //btn_S1ReadExpo_Click(null, null);
            //btn_S2ReadExpo_Click(null, null);
            //btn_ReadPrama_Click(null, null);

            //初始化权限状态
            PublicValue.LoginRight = 2;

            //加载设置
            Solutionpath = PublicFuntions.FindSolutionPath();
            finePic = Image.FromFile($"{Solutionpath}\\WindowsFormsApp2\\Resources\\fuxuankuang_2.png");
            abnormalPic = Image.FromFile($"{Solutionpath}\\WindowsFormsApp2\\Resources\\异常-红色.png");



            //// 获取当前屏幕的分辨率
            //Screen currentScreen = Screen.FromControl(this);
            //int currentWidth = currentScreen.Bounds.Width;
            //int currentHeight = currentScreen.Bounds.Height;

            //// 计算缩放比例
            //float scaleX = (float)currentWidth / DesignWidth;
            //float scaleY = (float)currentHeight / DesignHeight;

            //// 调整窗体大小（可选）
            //this.Size = new Size(
            //    (int)(this.Width * scaleX),
            //    (int)(this.Height * scaleY)
            //);

            //// 递归缩放所有控件
            //ScaleControl(this, scaleX, scaleY);


        }
        private const int DesignWidth = 1920;
        private const int DesignHeight = 1080;
        //缩放控件方法
        private void ScaleControl(Control control, float scaleX, float scaleY)
        {
            // 调整位置和大小
            control.Left = (int)(control.Left * scaleX);
            control.Top = (int)(control.Top * scaleY);
            control.Width = (int)(control.Width * scaleX);
            control.Height = (int)(control.Height * scaleY);

            // 调整字体大小（取最小比例防止拉伸）
            float fontSize = control.Font.Size * Math.Min(scaleX, scaleY);
            control.Font = new Font(control.Font.FontFamily, fontSize, control.Font.Style);

            // 递归处理子控件
            foreach (Control child in control.Controls)
            {
                ScaleControl(child, scaleX, scaleY);
            }
        }




        #region【初始化函数】
        private void AppINIT()
        {
            try
            {
                InitOK = true;
                welcomefrom.LoadingProgress(20, "系统初始化", 100);
                if (!InitPath())
                {
                    InitOK = false;
                }
                welcomefrom.LoadingProgress(30, "读取参数", 100);
                if (!ReadParameters())
                {
                    InitOK = false;
                }
                welcomefrom.LoadingProgress(50, "读取参数", 200);
                //if (!LightInit())
                //{
                //    RunLogMessage("光源控制器连接失败");
                //    InitOK = false;
                //}
                //图像处理初始化
                //welcomefrom.LoadingProgress(5, "图像处理初始化", 100);
                //if (!IPInit())
                //{
                //    InitOK = false;
                //}
                welcomefrom.LoadingProgress(70, "相机初始化", 500);
                if (!CameraInit())
                {
                    InitOK = false;
                }
                //PLC连接
                //welcomefrom.LoadingProgress(10, "PLC连接", 200);
                //if (!PLCInit())
                //{
                //    RunLogMessage("PLC连接失败！");
                //    InitOK = false;
                //}
                welcomefrom.LoadingProgress(50, "传感器初始化", 200);
                if (!SensorInit())
                {
                    RunLogMessage("传感器初始化失败！");
                    InitOK = false;
                }
                //Thread.Sleep(100);
                welcomefrom.LoadingProgress(100, "加载完成", 200);

                welcomefrom.CloseForm = true;


                //启动图像处理线程，处理图像
                //启动主线程
                main_thread.RunWorkerAsync();
                DoOtherWork.RunWorkerAsync();



                ExitSta = 1;
                if (InitOK)
                {
                    RunLogMessage("软件初始化完成!");
                    PublicValue.APPstatus = (int)PublicValue.APPstatusE.运行;
                    //触发一次自动设置                
                }
                else
                {
                    PublicValue.APPstatus = (int)PublicValue.APPstatusE.手动;
                    RunLogMessage("程序初始化失败,请检查相关配置");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

        }

        private bool SensorInit()
        {
            try
            {

                wheels[0] = Wheel1; wheels[1] = Wheel2;
                wheels[2] = Wheel3; wheels[3] = Wheel4;
                Jacks[0] = JackRightLeft; Jacks[1] = JackUpDown;


                //先打卡板卡
                int re = alignControl.boardInit();
                if (re == 0)
                {
                    RunLogMessage("控制卡初始化失败！");
                }
                //打开串口
                RopeSensorsCom.Close();
                RopeSensorsCom.Open();

                LaserCom.Close();
                LaserCom.Open();
                if (RopeSensorsCom.portOpen & LaserCom.portOpen)
                {
                    //打开读取线程、硬限位监控、轮距监控
                    bgw_ReadPosLimit.RunWorkerAsync();
                    bgw_HardLimitState.RunWorkerAsync();
                    Thread.Sleep(500);
                    bgw_WheelDisMonitor.WorkerSupportsCancellation = true;
                    bgw_WheelDisMonitor.RunWorkerAsync();

                    return true;
                }
                else
                {
                    RunLogMessage("传感器初始化失败，请检查COM口");
                    return false;
                }





            }
            catch (Exception)
            {

                return false;
            }
        }


        /// <summary>
        /// 初始化系统设置
        /// </summary>
        /// <returns></returns>
        private bool InitPath()
        {
            try
            {
                PublicValue.SystemIniPath = Application.StartupPath + @"\System.ini";
                PublicValue.StationINIpath[0] = Application.StartupPath + @"\Station1.ini";
                PublicValue.StationINIpath[1] = Application.StartupPath + @"\Station2.ini";
                PublicValue.StationINIpath[2] = Application.StartupPath + @"\Station3.ini";
                PublicValue.StationINIpath[3] = Application.StartupPath + @"\Station4.ini";
                PublicValue.StationINIpath[4] = Application.StartupPath + @"\Station5.ini";
                PublicValue.StationINIpath[5] = Application.StartupPath + @"\Station6.ini";
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        private void 窗口调整()
        {
            try
            {
                //=============================================居中显示主界面================================================
                Rectangle Rect = new Rectangle();
                Rect = Screen.GetWorkingArea(this);    //显示器分辨率
                int FormHeight = this.Height;          //窗体大小
                int FormWidth = this.Width;
                this.Location = new System.Drawing.Point((Rect.Width - FormWidth) / 2, (Rect.Height - FormHeight) / 2);


                //=============================================绑定图像窗口==================================================                       
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }
        private Boolean CameraInit()
        {

            //开启错边显示线程
            this.Invoke(new MethodInvoker(delegate
            {
                timer_UpdateCamWin.Start();

            }));

            try
            {
                bool tempflag = true;
                List<string> IPlist = new List<string>();
                Cmb_CamControlList.Items.Clear();


                CamControl7900.ID = 0;

                int Res2 = CamControl7900.ConnectDevice("192.168.0.10");
                if (CamControl7900.Connected == 1)
                {

                    RunLogMessage($"控制器{CamControl7900.ID}连接成功，IP：192.168.0.10");

                    //开启3相机的数据读取线程
                    bgw_ReadCams1.RunWorkerAsync();


                }
                else
                {
                    RunLogMessage($"控制器{CamControl7900.ID}连接失败，请检查网络，IP：192.168.0.10");
                    tempflag = false;
                }

                //控制器1连接
                CamControl7400_2.ID = 1;
                int Res = CamControl7400_2.ConnectDevice("192.168.1.10");
                if (CamControl7400_2.Connected == 1)
                {
                    //CamControl7400_2.ID = 1;
                    RunLogMessage($"控制器{CamControl7400_2.ID}连接成功，IP：192.168.1.10");

                    //开启12相机的数据读取线程
                    bgw_ReadCams23.RunWorkerAsync();


                }
                else
                {
                    RunLogMessage($"控制器{CamControl7400_2.ID}连接失败，请检查网络，IP：192.168.1.10");
                    tempflag = false;
                }




                return tempflag;





            }
            catch (Exception ex)
            {
                RunLogMessage("相机连接失败,请检查相机配置.");
                PublicFuntions.SaveErrorLog(PublicValue.LogPath, ex.ToString());
                return false;
            }
        }
        /// <summary>
        /// 读取参数,只读取全局变量参数
        /// </summary>
        /// <returns></returns>
        /// 
        //读参数，读取当前
        public Boolean ReadParameters()
        {
            try
            {
                //读取轴参数：零点、初始位
                SettingPath = Path.Combine(Application.StartupPath, "AxisSetting.json");
                if (File.Exists(SettingPath))
                {
                    try
                    {
                        string json = File.ReadAllText(SettingPath);//读取字符串
                        //将json字符串序列化给类型对象
                        axisSettings = JsonConvert.DeserializeObject<AxisSettings>(json);
                        propertyGrid1.SelectedObject = axisSettings;

                        Wheel1.ZeroPos = axisSettings.Axis1Zero;
                        Wheel2.ZeroPos = axisSettings.Axis2Zero;
                        Wheel3.ZeroPos = axisSettings.Axis3Zero;
                        Wheel4.ZeroPos = axisSettings.Axis4Zero;
                        Wheel1.ZeroPosOffSet = axisSettings.Axis1Start;
                        Wheel2.ZeroPosOffSet = axisSettings.Axis2Start;
                        Wheel3.ZeroPosOffSet = axisSettings.Axis3Start;
                        Wheel4.ZeroPosOffSet = axisSettings.Axis4Start;

                        this.CatchPart = axisSettings.CapPointNum;
                        this.VariThreshold = axisSettings.VariThreshold;
                        VariWindowWidth = axisSettings.VariWindowWidth;
                        HeightDisMax = axisSettings.HeightDisMax;
                        GapDisMax = axisSettings.GapDisMax;
                        HeightDisThreshold = axisSettings.HeightDisThreshold;
                        GapDisThreshold = axisSettings.GapDisThreshold;
                        WheelDisMax = axisSettings.WheelDisMax;

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"加载失败：{ex.Message}");
                    }
                }



                //=============================================读取系统配置参数===============================================
                //读取数据库参数
                //=============================================读取系统配置参数===============================================            
                PublicValue.LogPath = PublicFuntions.GetINI("System", "LogPath", "D:\\CCD日志", PublicValue.SystemIniPath);
                PublicValue.ResultCsvpath = PublicFuntions.GetINI("System", "生产记录", "D:\\生产数据", PublicValue.SystemIniPath);
                PublicValue.SaveImagePath = PublicFuntions.GetINI("System", "Camera1_SaveImagePath", "D:\\CCD图片",
                    PublicValue.SystemIniPath);

                PublicValue.DeleteImageTime = Convert.ToInt32(PublicFuntions.GetINI("System", "DeleteImageTime", "30",
                    PublicValue.SystemIniPath));
                PublicValue.DeleteLogTime = Convert.ToInt32(PublicFuntions.GetINI("System", "DeleteLogTime", "30",
                    PublicValue.SystemIniPath));
                PublicValue.ProductRecord = Convert.ToBoolean(PublicFuntions.GetINI("System", "ProductRecord", "false", PublicValue.SystemIniPath));
                PublicValue.ProductRecordDel = Convert.ToInt32(PublicFuntions.GetINI("System", "ProductRecordDel", "1",
                    PublicValue.SystemIniPath));
                PublicValue.ProductRecordPath = PublicFuntions.GetINI("System", "ProductRecordPath", "", PublicValue.SystemIniPath);

                if (PublicValue.ProductRecord) //判断是否选中保存生产数据文档，是则判断路径是否存在
                { PublicFuntions.CreateFile(PublicValue.ProductRecordPath); }

                //============================================读取相机配置参数========================================
                //工站1读取数据
                for (int i = 0; i < 6; i++)
                {
                    PublicValue.CameraSerialNum[i] = PublicFuntions.GetINI("工位配置信息", "相机序列号", "", PublicValue.StationINIpath[i]);
                    //===================图像处理数据读取===============
                    //读取图像路径,路径为完整路径 
                    PublicValue.mainHProgramPath[i] = PublicFuntions.GetINI("图像处理", "主函数路径", "", PublicValue.StationINIpath[i]);

                    PublicValue.DexposureTime[i] = Convert.ToDouble(PublicFuntions.GetINI("相机数据", "曝光时间", "", PublicValue.StationINIpath[i]));
                    //("相机数据", "曝光时间", exTime.ToString(), PublicValue.StationINIpath[0])
                    //读取输入参数
                    PublicValue.InPramas[i] = Convert.ToDouble(PublicFuntions.GetINI("输入参数", "参数1", "", PublicValue.StationINIpath[i]));
                    PublicValue.InPramas2[i] = Convert.ToDouble(PublicFuntions.GetINI("输入参数", "参数2", "", PublicValue.StationINIpath[i]));
                    //


                }
                //
                if (!File.Exists(PublicValue.PZprassavepath))
                {
                    外设.PZpras = new peizhiPras();
                }
                else
                {
                    外设.PZpras = (peizhiPras)XmlHelper.LoadXML<peizhiPras>(PublicValue.PZprassavepath);
                }
                //光源参数读取已经写好，直接用，写保存
                if (!File.Exists(PublicValue.Lightconfigpath_2D))
                {
                    外设.LightCtrl.cf = new SD2_24W124_Config();
                }
                else
                {
                    外设.LightCtrl.cf = (SD2_24W124_Config)XmlHelper.LoadXML<SD2_24W124_Config>(PublicValue.Lightconfigpath_2D);
                }





                //===================运动PLC相关数据===============
                if (!File.Exists(PublicValue.PLCconfigpath))
                {
                    外设.mudbus.cf = new PLCconfig();
                }
                else
                {
                    外设.mudbus.cf = (PLCconfig)XmlHelper.LoadXML<PLCconfig>(PublicValue.PLCconfigpath);
                }
                PLCConfig = (PLCconfig)外设.mudbus.cf;

                //if (File.Exists(PublicValue.StationPramaspath))
                //{
                //    stationPramas = (StationPramas)XmlHelper.LoadXML<StationPramas>(PublicValue.StationPramaspath);
                //    //qQlist = stationPramas.cla;
                //    SNNums = stationPramas.SNS;
                //}
                //else
                //{
                //    //File.Create(PublicValue.StationPramaspath);
                //}




                return true;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("参数读取失败！");
                return false;
            }
        }

        private Boolean IPInit()
        {
            try
            {
                //图像处理相关组件集合

                hWindowControls.Add(hWindowControl1); hWindowControls.Add(hWindowControl2);








                List<bool> tempresults = new List<bool>();
                for (int i = 0; i < PublicValue.mainHProgramPath.Count(); i++)
                {


                    if (PublicValue.mainHProgramPath[i].Trim() != null && PublicValue.mainHProgramPath[i].Trim() != "" && File.Exists(PublicValue.mainHProgramPath[i]))
                    {
                        try
                        {
                            HalconProgram2 = new HDevProgram(PublicValue.mainHProgramPath[i]);
                            hproduce = new HDevProcedure(HalconProgram2, "PreRunOnce");
                            //halcon代码实例
                            ProcCall = new HDevProcedureCall(hproduce);
                            hproduces2[i] = new HDevProcedure(HalconProgram2, "ImageProcess");
                            //halcon代码实例
                            ProcCalls2[i] = new HDevProcedureCall(hproduces2[i]);
                            ProcCall.SetInputCtrlParamTuple("TypeIndex", PublicValue.hv_modetype);
                            //设置输入图像
                            ProcCall.Execute();
                            tempoutobj = ProcCall.GetOutputIconicParamObject("OutObj1");
                            tempoutPras = ProcCall.GetOutputCtrlParamTuple("outPras");
                            //PublicValue.S1displines = ProcCall.GetOutputIconicParamObject("displines");
                            RunLogMessage("检测位" + (i + 1) + "加载图像处理成功");


                            tempresults.Add(true);
                        }
                        catch (Exception ex)
                        {
                            tempresults[i] = false;
                            RunLogMessage(ex.ToString());
                        }

                    }
                    else
                    {
                        RunLogMessage("工站" + (i + 1) + "未指明图像处理路径");
                        tempresults[i] = false;
                    }

                }
                //任意检测位NG，则返回NG
                bool result = true;
                foreach (var item in tempresults)
                {
                    if (!item)
                    {
                        result = false;
                    }

                }
                return result;
            }
            catch (Exception ex)
            {
                RunLogMessage("加载程序异常" + ex.ToString());
                return false;
            }
        }

        //板卡初始化
        //PLC连接初始化
        private Boolean PLCInit()
        {
            外设.mudbus.Connect();
            PublicValue.PLCresult = "";
            PublicValue.S2PLCresult = "";
            PublicValue.S3PLCresult = "";
            PublicValue.lastPLCstatus = "0";
            PublicValue.newPLCstatus = "0";
            PublicValue.S2lastPLCstatus = "0";
            PublicValue.S2newPLCstatus = "0";
            //初始化屏蔽信号


            if (外设.mudbus.Connection)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private Boolean LightInit()
        {
            Boolean tempresult = true;
            try
            {
                外设.LightCtrl.Connect();
                if (外设.LightCtrl.Connection)
                {
                    外设.LightCtrl.CloseAll();
                    if (外设.LightCtrl.OpenAll())
                    {
                        RunLogMessage("光源初始化成功");
                    }
                }
                else
                {
                    RunLogMessage("光源初始化失败");
                    tempresult = false;
                }


                return tempresult;

            }
            catch (Exception)
            {

                return false;
            }
        }
        #endregion

        #region 工具函数
        private void RunLogMessage(string LogMessage)
        {
            string LogTime = System.DateTime.Now.ToString("HH:mm:ss:fff");
            LogMessage = LogTime + ">>>" + LogMessage + "\r\n";
            //创建委托，用于访问主线程控件
            this.Invoke((EventHandler)delegate
            {

                rtb_Log.AppendText(LogMessage);
                //保持在最后一行显示
                rtb_Log.ScrollToCaret();
                if (rtb_Log.Lines.Length > 500)
                {
                    rtb_Log.Clear();
                }
            });
            PublicFuntions.SaveLog(PublicValue.LogPath, LogMessage);
        }

        //保存图像

        #endregion

        private void btn_AutoRun_Click(object sender, EventArgs e)
        {
            PublicValue.APPstatus = (int)PublicValue.APPstatusE.运行;  //开启自动取图
            this.lab_运行指示.Text = "运行";
            this.lab_运行指示.BackColor = Color.Green;
        }

        private void btn_StopMachine_Click(object sender, EventArgs e)
        {
            PublicValue.APPstatus = (int)PublicValue.APPstatusE.手动;  //开启自动取图  
            this.Invoke((EventHandler)delegate
            {
                this.lab_运行指示.Text = "停止";
                this.lab_运行指示.BackColor = Color.Red;
            });
        }

        private void btn_Vision_Click(object sender, EventArgs e)
        {
            视觉处理 tempForm = new 视觉处理();
            tempForm.Show();
        }

        private void btn_IO监控_Click(object sender, EventArgs e)
        {
            Frm_PLC通讯测试 tempform = new Frm_PLC通讯测试(外设.mudbus);
            tempform.Show();
        }

        private void btn_光源设置_Click(object sender, EventArgs e)
        {
            Frm_光源控制 tempF = new Frm_光源控制(外设.LightCtrl);
            tempF.Show();
        }
        private void btn_线扫光源1设置_Click(object sender, EventArgs e)
        {
            Frm_光源控制 tempF = new Frm_光源控制(外设.LightCtrl_xiansao1);
            tempF.Show();
        }
        private void btn_线扫光源2设置_Click(object sender, EventArgs e)
        {
            Frm_光源控制 tempF = new Frm_光源控制(外设.LightCtrl_xiansao2);
            tempF.Show();
        }
        private void btn_UseLogin_Click(object sender, EventArgs e)
        {
            if (PublicValue.LoginRight == 1)
            {
                Frm_Login tempFrom = new Frm_Login();
                tempFrom.Show();
            }
            else
            {
                PublicValue.LoginRight = 1;   //退回到普通级别
            }
        }

        int timecount = 0;
        private void DispInSign(int inNum, Label label, Color color, bool isHard)
        {
            if (!alignControl.ControlInit)
            {
                return;
            }
            try
            {
                if (inNum > 0 & inNum < 40)
                {
                    int re = Dmc1000.d1000_in_bit(inNum);
                    //若为低电平则有输入
                    if (re == 0)
                    {
                        label.BackColor = color;
                        if (isHard)
                        {
                            if (!SoftEmergencyFlag)
                            {
                                SoftEmergencyFlag = true;
                                RunLogMessage("严重警告：硬限位已触发");
                            }
                        }
                    }
                    else
                    {
                        label.BackColor = Color.White;
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }



        private void 显示_tick_Tick(object sender, EventArgs e)
        {
            #region[传感器连接状态]
            //控制连接状态显示
            if (LaserCom.portOpen)
            {
                lab_lasercon.Text = "已连接";
                lab_lasercon.BackColor = Color.Green;
            }
            else
            {
                lab_lasercon.Text = "未连接";
                lab_lasercon.BackColor = Color.Red;
            }
            if (RopeSensorsCom.portOpen)
            {
                lab_RopeConnect.Text = "已连接";
                lab_RopeConnect.BackColor = Color.Green;

            }
            else
            {
                lab_RopeConnect.Text = "未连接";
                lab_RopeConnect.BackColor = Color.Red;
            }
            if (CamControl7400_2.Connected == 1)
            {
                lab_Cam12Conne.Text = "已连接";
                lab_Cam12Conne.BackColor = Color.Green;
            }
            else
            {
                lab_Cam12Conne.Text = "未连接";
                lab_Cam12Conne.BackColor = Color.Red;
            }
            if (CamControl7900.Connected == 1)
            {
                lab_Cam3Conne.Text = "已连接";
                lab_Cam3Conne.BackColor = Color.Green;
            }
            else
            {
                lab_Cam3Conne.Text = "未连接";
                lab_Cam3Conne.BackColor = Color.Red;
            }

            #endregion

            #region[主流程界面控制]
            //开始停止旋转按钮

            if (alignControl.SpinstateB == 0)
            {
                btn_StartStopSpin.Text = "开始旋转";

            }
            else if (alignControl.SpinstateB == 1)
            {
                btn_StartStopSpin.Text = "停止旋转";
            }


            #endregion
            //更新组队滚轮架界面
            #region[更新组队滚轮架界面]
            //1滚轮内外移动信号
            #region[滚轮内外移动信号]
            switch (Wheel1.State)
            {
                case (Wheel.RunState)0:
                    //为0不移动，都为白色
                    btn_MoveIn1.BackColor = Color.White;
                    btn_MoveOut1.BackColor = Color.White;

                    break;
                case (Wheel.RunState)1:
                    //1w为内移动，内移动亮起
                    btn_MoveIn1.BackColor = Color.Lime;
                    btn_MoveOut1.BackColor = Color.White;
                    break;
                case (Wheel.RunState)2:
                    //为2外移动，亮起
                    btn_MoveIn1.BackColor = Color.White;
                    btn_MoveOut1.BackColor = Color.Lime;
                    break;
            }
            switch (Wheel2.State)
            {
                case (Wheel.RunState)0:
                    //为0不移动，都为白色
                    btn_MoveIn2.BackColor = Color.White;
                    btn_MoveOut2.BackColor = Color.White;

                    break;
                case (Wheel.RunState)1:
                    //1w为内移动，内移动亮起
                    btn_MoveIn2.BackColor = Color.Lime;
                    btn_MoveOut2.BackColor = Color.White;
                    break;
                case (Wheel.RunState)2:
                    //为2外移动，亮起
                    btn_MoveIn2.BackColor = Color.White;
                    btn_MoveOut2.BackColor = Color.Lime;
                    break;
            }
            switch (Wheel3.State)
            {
                case (Wheel.RunState)0:
                    //为0不移动，都为白色
                    btn_MoveIn3.BackColor = Color.White;
                    btn_MoveOut3.BackColor = Color.White;

                    break;
                case (Wheel.RunState)1:
                    //1w为内移动，内移动亮起
                    btn_MoveIn3.BackColor = Color.Lime;
                    btn_MoveOut3.BackColor = Color.White;
                    break;
                case (Wheel.RunState)2:
                    //为2外移动，亮起
                    btn_MoveIn3.BackColor = Color.White;
                    btn_MoveOut3.BackColor = Color.Lime;
                    break;
            }
            switch (Wheel4.State)
            {
                case (Wheel.RunState)0:
                    //为0不移动，都为白色
                    btn_MoveIn4.BackColor = Color.White;
                    btn_MoveOut4.BackColor = Color.White;

                    break;
                case (Wheel.RunState)1:
                    //1w为内移动，内移动亮起
                    btn_MoveIn4.BackColor = Color.Lime;
                    btn_MoveOut4.BackColor = Color.White;
                    break;
                case (Wheel.RunState)2:
                    //为2外移动，亮起
                    btn_MoveIn4.BackColor = Color.White;
                    btn_MoveOut4.BackColor = Color.Lime;
                    break;
            }
            //qianjd zhuangtai 
            switch (JackRightLeft.State)
            {
                case 0:
                    //为0不移动，都为白色
                    btn_JackLeft.BackColor = Color.White;
                    btn_JackRight.BackColor = Color.White;

                    break;
                case (Wheel.RunState)1:
                    //1w为内移动，内移动亮起
                    btn_JackLeft.BackColor = Color.Lime;
                    btn_JackRight.BackColor = Color.White;
                    break;
                case (Wheel.RunState)2:
                    //为2外移动，亮起
                    btn_JackLeft.BackColor = Color.White;
                    btn_JackRight.BackColor = Color.Lime;
                    break;
            }
            switch (JackUpDown.State)
            {
                case (Wheel.RunState)0:
                    //为0不移动，都为白色
                    btn_JackUp.BackColor = Color.White;
                    btn_JackDown.BackColor = Color.White;

                    break;
                case (Wheel.RunState)1:
                    //1w为内移动，内移动亮起
                    btn_JackUp.BackColor = Color.Lime;
                    btn_JackDown.BackColor = Color.White;
                    break;
                case (Wheel.RunState)2:
                    //为2外移动，亮起
                    btn_JackUp.BackColor = Color.White;
                    btn_JackDown.BackColor = Color.Lime;
                    break;
            }
            #endregion

            #region[监测显示输入信号]
            //读取8个滚轮极限位
            //分别检测状态并显示
            DispInSign(17, lab_OutHard1, Color.Red, true); DispInSign(18, lab_InHard1, Color.Red, true);
            DispInSign(20, lab_OutHard2, Color.Red, true); DispInSign(21, lab_InHard2, Color.Red, true);
            DispInSign(23, lab_OutHard3, Color.Red, true); DispInSign(24, lab_InHard3, Color.Red, true);
            DispInSign(26, lab_OutHard4, Color.Red, true); DispInSign(27, lab_InHard4, Color.Red, true);
            //原点
            DispInSign(19, lab_ZeroSign1, Color.Lime, false); DispInSign(22, lab_ZeroSign2, Color.Lime, false);
            DispInSign(25, lab_ZeroSign3, Color.Lime, false); DispInSign(28, lab_ZeroSign4, Color.Lime, false);
            DispInSign(29, lab_ZeroJackH, Color.Lime, false); DispInSign(30, lab_ZeroJackV, Color.Lime, false);
            //启动信号
            int re = Dmc1000.d1000_get_outbit(10);

            if (re == 0)
            {
                lab_Runsign.BackColor = Color.Lime;

            }
            else
            {
                lab_Runsign.BackColor = Color.White;
            }
            //急停信号
            if (alignControl.ControlInit)
            {

                if (Dmc1000.d1000_in_bit(31) == 0)
                {
                    //先全部停止
                    AllStopRun();
                    lab_EmergStop.Text = "已急停";
                    lab_EmergStop.BackColor = Color.Red;
                    RunLogMessage("处于急停状态");
                }
                else
                {
                    lab_EmergStop.Text = "正常运行";
                    lab_EmergStop.BackColor = Color.Chartreuse;
                }
                //手自动信号
                if (Dmc1000.d1000_in_bit(5) == 0)
                {
                    //先全部停止
                    AllStopRun();
                    lab_Controler.Text = "人工遥控";
                    lab_Controler.BackColor = Color.Gray;
                }
                else
                {
                    lab_Controler.Text = "软件控制";
                    lab_Controler.BackColor = Color.Chartreuse;
                }

            }

            //显示读取4滚轮计算的当前位置
            txb_Pos1.Text = Wheel1.CurrentPosition.ToString();
            txb_Pos2.Text = Wheel2.CurrentPosition.ToString();
            txb_Pos3.Text = Wheel3.CurrentPosition.ToString();
            txb_Pos4.Text = Wheel4.CurrentPosition.ToString();
            txb_jackHPos.Text = JackRightLeft.CurrentPosition.ToString();
            txb_jackVPos.Text = JackUpDown.CurrentPosition.ToString();
            txb_LaserPos.Text = PublicValue.LaserPos.ToString();
            //显示软限位
            //4轮软限位
            for (int i = 0; i < wheels.Length; i++)
            {
                if (wheels[i].SoftLimitNFlag)
                {

                    switch (i)
                    {
                        case 0:
                            lab_OutSoft1.BackColor = Color.Lime;
                            break;
                        case 1:
                            lab_OutSoft2.BackColor = Color.Lime;
                            break;
                        case 2:
                            lab_OutSoft3.BackColor = Color.Lime;
                            break;
                        case 3:
                            lab_OutSoft4.BackColor = Color.Lime;
                            break;


                    }

                }
                else if (wheels[i].SoftLimitPFlag)
                {

                    switch (i)
                    {
                        case 0:
                            lab_InSoft1.BackColor = Color.Lime;
                            break;
                        case 1:
                            lab_InSoft2.BackColor = Color.Lime;
                            break;
                        case 2:
                            lab_InSoft3.BackColor = Color.Lime;
                            break;
                        case 3:
                            lab_InSoft4.BackColor = Color.Lime;
                            break;



                    }

                }
                else
                {
                    lab_InSoft1.BackColor = Color.White; lab_InSoft2.BackColor = Color.White; lab_InSoft3.BackColor = Color.White;
                    lab_InSoft4.BackColor = Color.White;
                    lab_OutSoft1.BackColor = Color.White; lab_OutSoft2.BackColor = Color.White; lab_OutSoft3.BackColor = Color.White;
                    lab_OutSoft4.BackColor = Color.White;
                }


            }
            //千斤顶限位状态
            for (int i = 0; i < Jacks.Length; i++)
            {
                if (Jacks[i].SoftLimitNFlag)
                {

                    switch (i)
                    {

                        case 0:
                            lab_OutSoftJackH.BackColor = Color.Lime;
                            break;
                        case 1:
                            lab_OutSoftJackV.BackColor = Color.Lime;
                            break;

                    }

                }
                else if (wheels[i].SoftLimitPFlag)
                {

                    switch (i)
                    {

                        case 0:
                            lab_InSoftJackH.BackColor = Color.Lime;
                            break;
                        case 1:
                            lab_InSoftJackV.BackColor = Color.Lime;
                            break;


                    }

                }
                else
                {
                    lab_InSoftJackH.BackColor = Color.White; lab_InSoftJackV.BackColor = Color.White;
                    lab_OutSoftJackH.BackColor = Color.White; lab_OutSoftJackV.BackColor = Color.White;
                }


            }


            #endregion


            #endregion
            //更新后方滚轮架界面
            #region [更新后方滚轮架界面]
            //kaiqizhuangtai
            switch (alignControl.RunflagB)
            {
                case true:
                    //为真则把按钮界面显示为可停止
                    btn_StartStopRunB.Text = "停止";
                    btn_StartStopRunB.BackColor = Color.Red;
                    //忘了，把按钮开放
                    btn_Runmodel.Enabled = true;
                    btn_SpinDown.Enabled = true;
                    btn_SpinUp.Enabled = true;
                    btn_MovePositive.Enabled = true;
                    btn_MoveNegative.Enabled = true;
                    btn_SpeedDown.Enabled = true;
                    btn_SpeedUp.Enabled = true;
                    break;
                case false:
                    //为jia则把按钮界面显示为可kaiqi
                    btn_StartStopRunB.Text = "启动";
                    btn_StartStopRunB.BackColor = Color.Green;
                    //把按钮屏蔽
                    btn_Runmodel.Enabled = false;
                    btn_SpinDown.Enabled = false;
                    btn_SpinUp.Enabled = false;
                    btn_MovePositive.Enabled = false;
                    btn_MoveNegative.Enabled = false;
                    btn_SpeedDown.Enabled = false;
                    btn_SpeedUp.Enabled = false;

                    break;
            }
            switch (alignControl.RunModelB)
            {
                case 1:
                    //为1则把按钮界面显示为移动状态，黄色
                    lab_Runmodel.Text = "移动";
                    lab_Runmodel.BackColor = Color.Gold;
                    //把转动按钮屏蔽
                    btn_SpinUp.Enabled = false;
                    btn_SpinDown.Enabled = false;
                    btn_MovePositive.Enabled = true;
                    btn_MoveNegative.Enabled = true;
                    break;
                case 2:
                    //为2则把按钮界面显示为转动状态，蓝色
                    lab_Runmodel.Text = "转动";
                    lab_Runmodel.BackColor = Color.SkyBlue;
                    btn_SpinUp.Enabled = true;
                    btn_SpinDown.Enabled = true;
                    btn_MovePositive.Enabled = false;
                    btn_MoveNegative.Enabled = false;
                    break;
            }
            //转动状态控制更新
            switch (alignControl.SpinstateB)
            {
                case 0:
                    //为0则把按钮界面显示为可旋转
                    btn_SpinUp.Text = "正转";
                    btn_SpinDown.Text = "反转";
                    btn_SpinUp.BackColor = Color.White;
                    btn_SpinDown.BackColor = Color.White;
                    btn_SpinUp.Enabled = true;
                    btn_SpinDown.Enabled = true;
                    btn_Runmodel.Enabled = true;

                    break;
                case 1:
                    //为1是上旋转则把按钮界面显示为可停止
                    btn_SpinUp.Text = "停止正转";
                    btn_SpinUp.BackColor = Color.Lime;
                    btn_SpinDown.Text = "反转";
                    btn_SpinDown.Enabled = false;
                    btn_Runmodel.Enabled = false;//把切换按钮也关掉


                    break;
                case 2:
                    ///为2是下旋转则把按钮界面显示为可停止,不可其他移动
                    btn_SpinUp.Text = "正转";
                    btn_SpinDown.Text = "停止反转";
                    btn_SpinDown.BackColor = Color.Lime;
                    btn_SpinUp.Enabled = false;
                    btn_Runmodel.Enabled = false;//把切换按钮也关掉
                    break;
            }
            //移动状态控制更新
            switch (alignControl.MovestateB)
            {
                case 0:
                    //为0则把按钮界面显示为可移动
                    btn_MovePositive.Text = "正移动";
                    btn_MoveNegative.Text = "反移动";
                    btn_MovePositive.BackColor = Color.White;
                    btn_MoveNegative.BackColor = Color.White;
                    btn_MovePositive.Enabled = true;
                    btn_MoveNegative.Enabled = true;
                    btn_Runmodel.Enabled = true;

                    break;
                case 1:
                    //为1是正移动按钮界面显示为可停止
                    btn_MovePositive.Text = "停止正移动";
                    btn_MovePositive.BackColor = Color.Lime;
                    btn_MoveNegative.Text = "反移动";
                    btn_MoveNegative.Enabled = false;
                    btn_Runmodel.Enabled = false;//把切换按钮也关掉


                    break;
                case 2:
                    ///为2是下旋转则把按钮界面显示为可停止,不可其他移动
                    btn_MovePositive.Text = "正移动";
                    btn_MoveNegative.Text = "停止反移动";
                    btn_MoveNegative.BackColor = Color.Lime;
                    btn_MovePositive.Enabled = false;
                    btn_Runmodel.Enabled = false;//把切换按钮也关掉
                    break;
            }



            #endregion






            //ui刷新
            switch (PublicValue.APPstatus)
            {
                case 0:
                    //this.btn_AutoRun.Enabled = true;
                    //this.btn_StopMachine.Enabled = false;
                    break;
                case 1:
                    this.lab_运行指示.Text = "运行";
                    this.lab_运行指示.BackColor = Color.Green;
                    break;
                case 2:
                    this.lab_运行指示.Text = "停止";
                    this.lab_运行指示.BackColor = Color.Red;
                    break;
                case 3:
                    break;

                default:
                    break;
            }

            //更新显示


            if (PublicValue.LoginRight == 1)
            {
                this.tool_UseName.Text = "操作员";
                this.skinButt_login.Text = "权限登录";

            }
            else if (PublicValue.LoginRight == 2)
            {
                this.tool_UseName.Text = "技术员";
                this.skinButt_login.Text = "权限登出";
            }
            else if (PublicValue.LoginRight == 3)
            {
                this.tool_UseName.Text = "管理员";
                this.skinButt_login.Text = "权限登出";
            }
            //
            this.tool_UseRAM.Text = PublicFuntions.GetSoftWareARM();
            string CtotalV = PublicFuntions.GetHardDiskSpace("C").ToString();
            string CremainV = PublicFuntions.GetHardDiskFreeSpace("C").ToString();
            this.tool_ARMUseNum1.Text = CremainV + "/" + CtotalV;
            CtotalV = PublicFuntions.GetHardDiskSpace("D").ToString();
            CremainV = PublicFuntions.GetHardDiskFreeSpace("D").ToString();
            this.tool_ARMUseNum2.Text = CremainV + "/" + CtotalV;
            //
            //更新生产数据

            int SUMALL = 外设.PZpras.SUM_NGNUM + 外设.PZpras.SUM_OKNUM;
            int sum2 = 外设.PZpras.s2_NGNUM + 外设.PZpras.s2_OKNUM;
            int sum3 = 外设.PZpras.s3_NGNUM + 外设.PZpras.s3_OKNUM;
            double lianglv1 = 1.0;
            double lianglv2 = 1.0;
            double lianglv3 = 1.0;
            if (SUMALL != 0)
            {
                lianglv1 = 外设.PZpras.SUM_OKNUM / (double)SUMALL;
            }
            if (sum2 != 0)
            {
                lianglv2 = 外设.PZpras.SUM_OKNUM / (double)SUMALL;
            }
            if (sum3 != 0)
            {
                lianglv3 = 外设.PZpras.SUM_OKNUM / (double)SUMALL;
            }


            外设.PZpras.SUM = 外设.PZpras.SUM_NGNUM + 外设.PZpras.SUM_OKNUM;



            //保存生产数据
            //PublicFuntions.WriteINI("生产统计", "NGnum", PublicValue.NGnum.ToString(), PublicValue.SystemIniPath);
            //PublicFuntions.WriteINI("生产统计", "OKnum", PublicValue.OKnum.ToString(), PublicValue.SystemIniPath);




            //更新权限设置
            if (PublicValue.LoginRight == 1)
            {
                //  this.tabControl1.Enabled = false;
                this.btn_IO监控.Enabled = false;
                this.btn_Vision.Enabled = false;
                this.btn_光源设置.Enabled = false;
                this.参数.Parent = null;

            }
            else if (PublicValue.LoginRight == 2)
            {
                // this.tabControl1.Enabled = true;

                this.btn_IO监控.Enabled = false;
                this.btn_Vision.Enabled = false;
                this.btn_光源设置.Enabled = false;
                this.参数.Parent = this.tabControl1;

            }
            else if (PublicValue.LoginRight == 3)
            {
                this.btn_IO监控.Enabled = true;
                this.btn_Vision.Enabled = true;
                this.btn_光源设置.Enabled = true;
                this.参数.Parent = this.tabControl1;

            }


            //根据初始化状态控制权限





            timecount++;
            if (this.timecount > 10)
            {
                this.timecount = 0;
            }
            //实时显示
            #region 处理实时显示
            for (int i = 0; i < 3; i++)
            {
                if (PublicValue.isLiveFlag[i])
                {
                    switch (i)
                    {
                        case 0:
                            外设.Camera.softTriggerExcute();
                            break;
                        case 1:
                            外设.Camera2.softTriggerExcute();
                            break;
                        case 2:
                            外设.Camera3.softTriggerExcute();
                            break;
                    }
                }
            }
            #endregion
        }

        private void main_thread_DoWork(object sender, DoWorkEventArgs e)
        {
            //定义两个计时器
            while (ExitSta == 1)
            {
                try
                {
                    switch (PublicValue.APPstatus)
                    {
                        case 1:     //正常运行模式
                            AutoRun();
                            break;
                        case 2:     //停止1，指示单纯的停机模式，其他信号正常
                            stop1();
                            break;
                        case 5:
                            Errstop();
                            break;
                        default:
                            break;

                    }

                }
                catch (Exception ex)
                {
                    PublicFuntions.SaveErrorLog(PublicValue.LogPath, ex.ToString());
                }
                Thread.Sleep(5);
            }
        }
        //





        /// <summary>
        /// 自动流程
        /// </summary>

        Stopwatch S1timeCosum = new Stopwatch();  //工位1图像处理耗时，计时器

        int RunStep = 0;  //0:准备阶段  1：拉近阶段 2：对准阶段 3：点焊阶段 4：后推阶段
        //流程处理，耗时计算在自动工站给出
        private void AutoRun()
        {

            RunStep = 0;
            S1timeCosum.Restart();  //开始计数,
            RunFlag = true;

            try
            {
                #region 主流程
                while (RunFlag)
                {


                    //先完成3次拍照后再进行图像处理
                    switch (RunStep)
                    {
                        //等待状态
                        case -1:
                            break;
                        //准备状态
                        case 0:
                            //阶段信息
                            lab_stateName.Text = "准备阶段";
                            lab_StateAbout.Text = "";
                            lab_StateDetail.Text = "";
                            prb_StateProcess.Value = 0;
                            //更新整体流程颜色
                            UpdateStatesLab(RunStep);


                            break;
                        case 1:
                            //拉近阶段
                            //阶段信息
                            lab_stateName.Text = "拉近阶段";
                            lab_StateAbout.Text = "";
                            lab_StateDetail.Text = "";
                            prb_StateProcess.Value = 0;
                            //更新整体流程颜色
                            UpdateStatesLab(RunStep);

                            PullIn(20, 50000);

                            RunStep = 2;
                            break;
                        case 2:
                            //对准阶段
                            //阶段信息
                            lab_stateName.Text = "对准阶段";
                            lab_StateAbout.Text = "系统根据3位置错边和间隙自动逐一调整各方向偏差";
                            //更新整体流程颜色
                            UpdateStatesLab(RunStep);



                            lab_StateDetail.Text = "自动矫正RZ中";
                            prb_StateProcess.Value = 0;
                            CorrectRotaZ(0.5, 5000, 10);
                            RunStep = 22;
                            break;
                        case 22:
                            //对准阶段
                            //阶段信息


                            lab_StateDetail.Text = "自动矫正RY中";
                            prb_StateProcess.Value = 10;
                            CorrectRotaY(0.5, 5000, 10);
                            RunStep = 23;
                            break;


                        case 23:
                            //对准阶段
                            //阶段信息




                            lab_StateDetail.Text = "自动矫正Y中";
                            prb_StateProcess.Value = 20;
                            CorrectRotaZ(0.5, 5000, 10);
                            break;







                        case 24:
                            //对准阶段
                            //阶段信息




                            lab_StateDetail.Text = "自动矫正Z中";
                            prb_StateProcess.Value = 80;
                            CorrectRotaZ(0.5, 5000, 10);
                            //调整完成自动进入点焊阶段
                            RunStep = 3;
                            break;

                        case 3:

                            //点焊阶段
                            //阶段信息
                            lab_stateName.Text = "点焊阶段";
                            lab_StateAbout.Text = "人工开始旋转点焊，同时系统自动校正点焊处错边";
                            //更新整体流程颜色
                            UpdateStatesLab(RunStep);



                            lab_StateDetail.Text = "自动旋转点焊中";
                            prb_StateProcess.Value = 50;
                            //开始自动矫正线程
                            bgw_StartCorrect.RunWorkerAsync();

                            //进入等待
                            RunStep = -1;



                            break;
                        case 4:

                            //后推阶段
                            //阶段信息
                            lab_stateName.Text = "后推阶段";
                            lab_StateAbout.Text = "系统自动后推焊接后的塔筒";
                            //更新整体流程颜色
                            UpdateStatesLab(RunStep);



                            lab_StateDetail.Text = "自动后推中";
                            prb_StateProcess.Value = 50;
                            //开始自动矫正线程
                            MoveBack(5000);


                            //进入准备阶段
                            RunStep = 0;



                            break;

                    }
                    Thread.Sleep(1);
                }
                #endregion
            }
            catch (Exception ex)
            {


                //异常当做NG
                RunLogMessage(ex.ToString());
            }

            S1timeCosum.Stop();
            RunLogMessage("工位1耗时" + (S1timeCosum.ElapsedMilliseconds / 1000.0).ToString());




        }
        //定义各产品对应的显示窗口
        public void UpdateStatesLab(int step)
        {
            switch (step)
            {
                case 0:
                    lab_PrepareState.BackColor = Color.Gold;
                    lab_PullState.BackColor = Color.DarkGray;
                    lab_AlignState.BackColor = Color.DarkGray;
                    lab_WorkState.BackColor = Color.DarkGray;
                    lab_PushState.BackColor = Color.DarkGray;
                    //控制千斤顶、旋转按钮
                    btn_StartStopSpin.Enabled = false; ;
                    btn_Jackstartstop.Enabled = false;
                    btn_resetAll.Enabled = true;
                    btn_StartPush.Enabled = false;

                    break;
                case 1:
                    lab_PrepareState.BackColor = Color.Lime;
                    lab_PullState.BackColor = Color.Gold;
                    lab_AlignState.BackColor = Color.DarkGray;
                    lab_WorkState.BackColor = Color.DarkGray;
                    lab_PushState.BackColor = Color.DarkGray;
                    btn_StartStopSpin.Enabled = false; ;
                    btn_Jackstartstop.Enabled = false;
                    btn_resetAll.Enabled = false;
                    btn_StartPush.Enabled = false;

                    break;
                case 2:
                    lab_PrepareState.BackColor = Color.Lime;
                    lab_PullState.BackColor = Color.Lime;
                    lab_AlignState.BackColor = Color.Gold;
                    lab_WorkState.BackColor = Color.DarkGray;
                    lab_PushState.BackColor = Color.DarkGray;
                    btn_StartStopSpin.Enabled = false; ;
                    btn_Jackstartstop.Enabled = false;
                    btn_resetAll.Enabled = false;
                    btn_StartPush.Enabled = false;
                    break;
                case 3:
                    lab_PrepareState.BackColor = Color.Lime;
                    lab_PullState.BackColor = Color.Lime;
                    lab_AlignState.BackColor = Color.Lime;
                    lab_WorkState.BackColor = Color.Gold;
                    lab_PushState.BackColor = Color.DarkGray;
                    btn_StartStopSpin.Enabled = true; ;
                    btn_Jackstartstop.Enabled = true;
                    btn_resetAll.Enabled = false;
                    btn_StartPush.Enabled = false;
                    break;
                case 4:
                    lab_PrepareState.BackColor = Color.Lime;
                    lab_PullState.BackColor = Color.Lime;
                    lab_AlignState.BackColor = Color.Lime;
                    lab_WorkState.BackColor = Color.Lime;
                    lab_PushState.BackColor = Color.Gold;
                    btn_StartStopSpin.Enabled = false; ;
                    btn_Jackstartstop.Enabled = false;
                    btn_resetAll.Enabled = false;
                    btn_StartPush.Enabled = true;
                    break;


            }


        }



        private void DispNG()
        {
            for (int i = 0; i < Results.Count; i++)
            {
                if (Results[i] == "OK")
                {
                    NGLabels[i].BackColor = Color.Green;
                }
                else
                {
                    NGLabels[i].BackColor = Color.Red;
                }
            }
        }

        private void ImageTest(HObject HImage, HTuple InPrama, HTuple InPrama2, HWindowControl hWindowControl, HDevProcedureCall hDevProcedureCall, Label label, out string Result)
        {
            hDevProcedureCall.SetInputIconicParamObject("InputObj", tempoutobj);//调用
            hDevProcedureCall.SetInputCtrlParamTuple("InputPras", InPrama);
            hDevProcedureCall.SetInputCtrlParamTuple("InputPras2", InPrama2);
            hDevProcedureCall.SetInputIconicParamObject("Image", HImage);
            hDevProcedureCall.Execute();
            Result = hDevProcedureCall.GetOutputCtrlParamTuple("result").S;
            HTuple outmessage = hDevProcedureCall.GetOutputCtrlParamTuple("outMessage").S;
            HObject outobjOK = hDevProcedureCall.GetOutputIconicParamObject("OutObjOK");
            HObject outobjNG = hDevProcedureCall.GetOutputIconicParamObject("OutObjNG");

            HOperatorSet.SetLineWidth(hWindowControl.HalconWindow, 4);


            //if (outobjNG!=null)
            //{
            HOperatorSet.SetColor(hWindowControl.HalconWindow, "red");
            HOperatorSet.SetDraw(hWindowControl.HalconWindow, "margin");
            HOperatorSet.DispObj(outobjNG, hWindowControl.HalconWindow);
            //}
            HOperatorSet.SetLineWidth(hWindowControl.HalconWindow, 2);

            HOperatorSet.SetColor(hWindowControl.HalconWindow, "green");
            HOperatorSet.SetDraw(hWindowControl.HalconWindow, "margin");
            HOperatorSet.DispObj(outobjOK, hWindowControl.HalconWindow);

            HOperatorSet.SetLineWidth(hWindowControl.HalconWindow, 8);
            HOperatorSet.SetTposition(hWindowControl.HalconWindow, 10, 400);
            HOperatorSet.WriteString(hWindowControl.HalconWindow, outmessage);

            //outobjNG.Dispose();
            //outobjOK.Dispose();

            if (Result == "OK")
            {
                label.Text = "OK";
                label.BackColor = Color.Green;

            }
            else
            {
                label.Text = "NG";
                label.BackColor = Color.Red;
            }
        }
        private void RespondPLC()
        {
            try
            {
                if (!camera_Run)
                {
                    外设.mudbus.WriteD(PLCConfig.HResultaddress, "1");
                    RunLogMessage("PLC结果已屏蔽 ");



                }
                else
                {
                    if (Results.Contains("NG"))
                    {
                        //向PLC发送结果
                        外设.mudbus.WriteD(PLCConfig.HResultaddress, "2");
                        RunLogMessage("结果NG");

                    }

                    else
                    {

                        外设.mudbus.WriteD(PLCConfig.HResultaddress, "1");
                        RunLogMessage("结果OK ");
                    }
                }

            }
            catch (Exception ex)
            {

                RunLogMessage("回复PLC失败");
                RunLogMessage(ex.ToString());

            }
        }





        private void stop1()
        {
            ////保证循环停止
            //if (ProfileGet.Enabled)
            //{
            //    //在非UI线程中操作UI，需要invoke
            //    this.Invoke(new MethodInvoker(delegate
            //    {
            //        ProfileGet.Enabled = false;
            //    }));
            //}

        }
        //停止2模式，不相应动作，只响应复位按钮
        private void Errstop()
        {
            //先处理输入
            //显示当前状态
            this.Invoke((EventHandler)delegate
            {
                this.lab_运行指示.Text = "故障";
                this.lab_运行指示.BackColor = Color.Red;
            });
        }



        private void DoOtherWork_DoWork(object sender, DoWorkEventArgs e)
        {
            while (ExitSta == 1)
            {
                try
                {
                    for (int i = 0; i < 6; i++)
                    {


                    }
                    //自动删除超出间隔时间的文件

                    PublicFuntions.DeleateFile(PublicValue.LogPath, PublicValue.DeleteLogTime);                                     //日志记录
                    if (PublicValue.ProductRecord)          //如果选中保存文档，则定期删除生产文档数据
                    { PublicFuntions.DeleateFile(PublicValue.ProductRecordPath, PublicValue.ProductRecordDel); }
                }
                catch (Exception ex)
                {
                    PublicFuntions.SaveErrorLog(PublicValue.LogPath, ex.ToString());
                }
                Thread.Sleep(10000);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dr = MessageBox.Show("\r确定退出软件吗?", "系统提示", MessageBoxButtons.OKCancel);
            if (dr == DialogResult.OK)
            {
                //保存配置数据
                //  XmlHelper.SaveXML(PublicValue.PZprassavepath, 外设.PZpras);
                ExitSta = 0;
                Thread.Sleep(100);

                //结束进程
                //bgw_HardLimitState.CancelAsync();
                //bgw_HardLimitState.Dispose();
                //bgw_ReadCams1.CancelAsync();
                //bgw_ReadCams23.CancelAsync();
                //bgw_ReadPosLimit.CancelAsync();
                //bgw_WheelDisMonitor.CancelAsync();
                bgw_WheelDisMonitor.CancelAsync();


                //关掉相机

                //批处理停止
                CamControl7400_2.StopMeasure();
                CamControl7900.StopMeasure();

                //关闭设备
                CamControl7400_2.DisconnectDevice();
                CamControl7900.DisconnectDevice();

                AllStopRun();

                Thread.Sleep(100);

                if (外设.mudbus.Connection)
                {
                    外设.mudbus.Close();
                }
                Thread.Sleep(100);
                //串口关闭
                if (外设.LightCtrl.Connection)
                {
                    //关闭所有通道
                    外设.LightCtrl.CloseAll();
                    Thread.Sleep(100);
                    外设.LightCtrl.Close();
                }
                if (RopeSensorsCom.portOpen)
                {
                    RopeSensorsCom.Close();
                }
                if (LaserCom.portOpen)
                {
                    LaserCom.Close();
                }
                //stationPramas.cla = qQlist;
                stationPramas.SNS = SNNums;
                XmlHelper.SaveXML(PublicValue.StationPramaspath, stationPramas);


            }
            else
            {
                e.Cancel = true;
            }
        }



        private void tabPage2_TextChanged(object sender, EventArgs e)
        {

        }


        private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
        {

        }





        private void hWindowControl2_HMouseMove(object sender, HMouseEventArgs e)
        {

        }







        private void btn_清空日志显示_Click(object sender, EventArgs e)
        {
            this.rtb_Log.Clear();

        }

        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void btn_ImageFrm_Click(object sender, EventArgs e)
        {
            try
            {
                if (Process.Start("explorer.exe", PublicValue.SaveImagePath) == null)
                {
                    RunLogMessage("图片目录打开失败");
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        private void Loglist_Click(object sender, EventArgs e)
        {
            try
            {
                if (Process.Start("explorer.exe", PublicValue.LogPath) == null)
                {
                    RunLogMessage("日志目录打开失败");
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }







        private void btn_ClearNum_Click(object sender, EventArgs e)
        {
            外设.PZpras.SUM = 0;
            外设.PZpras.SUM_NGNUM = 0;
            外设.PZpras.SUM_OKNUM = 0;
            外设.PZpras.SUM_Failed = 0;
            for (int i = 0; i < 外设.PZpras.StaionNGNums.Length; i++)
            {
                外设.PZpras.StaionNGNums[i] = 0;
            }


            if (XmlHelper.SaveXML(PublicValue.PZprassavepath, 外设.PZpras) == "")
            {
                MessageBox.Show("保存成功");
            }
            else
            {
                MessageBox.Show("保存失败");
            }
            RunLogMessage("数据清零成功！");
        }






        #region 3D相机控制

        SsznCamControl CamControl7400_2 = new SsznCamControl();
        SsznCamControl CamControl7900 = new SsznCamControl();
        int[][] CurrentProfile = new int[3][];
        //截取点数
        int CatchPart = 3200;
        //方差核宽度
        int VariWindowWidth = 5;
        //方差阈值
        double VariThreshold = 5;
        //错边报警阈值
        public double HeightDisMax = 2;
        //间隙报警阈值
        public double GapDisMax = 2;



        //间隙差值阈值,mm
        public double HeightDisThreshold = 2;
        //错边差值阈值,mm
        public double GapDisThreshold = 2;
        //同侧轮差距报警阈值,mm
        public double WheelDisMax = 150;


        //1为焊接侧传感器7900
        double DispHeightDis1 = 0;
        double DispGap1 = 0;
        //2为非焊接测传感器7400-1
        double DispHeightDis2 = 0;
        double DispGap2 = 0;
        //3为底部传感器7400-2
        double DispHeightDis3 = 0;
        double DispGap3 = 0;

        private void Btn_SearchCamControl_Click(object sender, EventArgs e)
        {
            try
            {
                Cmb_CamControlList.Items.Clear();
                int DeviceCount;
                byte[][] IpAddressList1;
                CamControl7400_2.GetIPAddressList(out DeviceCount, out IpAddressList1);
                if (DeviceCount > 0)
                {
                    for (int i = 0; i < DeviceCount; i++)
                    {
                        Cmb_CamControlList.Items.Add(IpAddressList1[i][0].ToString() + "." + IpAddressList1[i][1].ToString()
                            + "." + IpAddressList1[i][2].ToString() + "." + IpAddressList1[i][3].ToString());
                    }
                }
                else
                {
                    RunLogMessage("未找到控制器");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void Btn_Connect_Click(object sender, EventArgs e)
        {
            int res = CamControl7400_2.ConnectDevice(Cmb_CamControlList.Text);
            if (res == 0)
            {
                RunLogMessage($"控制器连接成功，IP：{Cmb_CamControlList.Text}");
            }
        }

        private void Btn_DisConnect_Click(object sender, EventArgs e)
        {
            //批处理停止
            CamControl7400_2.StopMeasure();

            //关闭设备
            CamControl7400_2.DisconnectDevice();
        }

        private void Btn_StartSnap_Click(object sender, EventArgs e)
        {

        }

        private void btn_SoftTrigOne_Click(object sender, EventArgs e)
        {

        }

        private void GetProfileBtn_Click(object sender, EventArgs e)
        {
            try
            {
                SsznCamControl ssznCamControl;
                switch (cmb_testCamNum.SelectedIndex)
                {
                    case 0:
                        ssznCamControl = this.CamControl7900;
                        break;
                    case 1:
                        ssznCamControl = this.CamControl7400_2;
                        break;
                    case 2:
                        ssznCamControl = this.CamControl7400_2;
                        break;
                    default:
                        break;
                }
                int[] _Profile;
                uint[] _EncoderData;
                int err = CamControl7400_2.GetProfile(out _Profile, out _EncoderData);

                if (err == 0)
                {

                    //计算轮廓

                    int cut = this.CatchPart;
                    ProfileProcess.GetNumsByInvalidSegment(_Profile, cut, out double heightDis, out double gap);
                    DispGap1 = gap;
                    DispHeightDis1 = heightDis;

                    //保存轮廓
                    ProfileProcess.SaveIntArrayToCSV(_Profile, PublicValue.CSVRootPath);

                    //输出图像
                    Bitmap bitmap = CamControl7400_2.ProfileTobmp(_Profile, cut, 1000, 3200);

                    ProfileProcess.Profile2bmp(_Profile, cut, 1000, out Bitmap bitmap1);
                    bitmap1.Save("D:\\Work\\研究院\\钢卷拼接\\软件\\testimage\\testim.bmp");

                    HObject hObject = PublicFuntions.ConvertBitmapToHObject(bitmap1);

                    PublicFuntions.DispImage(hObject, hWindowControl1.HalconWindow);
                    RunLogMessage("保存单条轮廓成功");
                }
                else
                {
                    RunLogMessage("获取轮廓失败，请检查批处理模式是否关闭");
                }
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }




        #endregion

        #region 计米器测试

        Socketconnect JMConnect = new Socketconnect();
        byte[] recover = { 0x01, 0x06, 0x00, 0x00, 0x00, 0x02, 0x08, 0x0B };
        byte[] stop = { 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x88, 0x09 };
        byte[] start = { 0x01, 0x06, 0x00, 0x00, 0x00, 0x08, 0x88, 0x0C };
        byte[] read = { 0x01, 0x03, 0x00, 0x21, 0x00, 0x02, 0x94, 0x01 };
        private void btn_JMconnect_Click(object sender, EventArgs e)
        {
            try
            {

                JMConnect.controlIP = txb_JMQIP.Text;
                JMConnect.port = Convert.ToInt16(txb_port.Text);
                if (JMConnect.connect())
                {
                    MessageBox.Show($"连接成功，IP：{JMConnect.controlIP},port:{JMConnect.port}");
                }
                else
                {
                    MessageBox.Show($"连接失败，IP：{JMConnect.controlIP},port:{JMConnect.port}");
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }
        private void btn_JMDiscon_Click(object sender, EventArgs e)
        {
            try
            {

                JMConnect.disconnect();

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_Send_Click(object sender, EventArgs e)
        {
            try
            {
                if (JMConnect.ConnectionState == 1)
                {
                    JMConnect.SendStr(txb_mes.Text);

                }
                else
                {
                    MessageBox.Show($"未连接");
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_Recover_Click(object sender, EventArgs e)
        {
            try
            {

                JMConnect.SendBytes(recover);
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_start_Click(object sender, EventArgs e)
        {
            try
            {

                JMConnect.SendBytes(start);
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_stop_Click(object sender, EventArgs e)
        {
            try
            {

                JMConnect.SendBytes(stop);
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_read_Click(object sender, EventArgs e)
        {
            try
            {

                JMConnect.SendBytes(read);


            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }
        #endregion



        private void btn_getProfFromCSV_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "CSV|*.csv";
            dlg.Title = "选择csv文件";

            DialogResult result = dlg.ShowDialog();
            if (result == DialogResult.OK)
            {
                string csvpath = dlg.FileName;
                int[] Profile = ProfileProcess.ReadHeightDataFromCsv(csvpath);
                int cut = CatchPart;
                ProfileProcess.Profile2bmp(Profile, cut, 1000, out Bitmap bitmap1);
                bitmap1.Save("D:\\Work\\研究院\\钢卷拼接\\软件\\testimage\\testim1.bmp");

                HObject hObject = PublicFuntions.ConvertBitmapToHObject(bitmap1);
                PublicFuntions.DispImage(hObject, hWindowControl1.HalconWindow);



                Stopwatch sw = new Stopwatch();
                sw.Start();
                int PlatfNum = ProfileProcess.FindNumsByPlatforms(Profile, cut, VariWindowWidth, VariThreshold, 10, 0.18, out double heightDis, out double gap);

                Console.WriteLine($"处理耗时：{sw.ElapsedMilliseconds}ms");
                sw.Stop();
                if (PlatfNum == 1)
                {

                    RunLogMessage("无间隙和错边");

                }
                else if (PlatfNum == 0)
                {
                    RunLogMessage("未检测到塔筒壁");

                }
                else if (PlatfNum > 2)
                {
                    RunLogMessage("塔筒表面存在凸起或异物！");

                }
                else if (PlatfNum == -1)
                {
                    RunLogMessage("检测异常");
                }
                DispGap1 = gap;
                DispHeightDis1 = heightDis;
            }



        }



        #region 【485设备测试】
        COM_ModbusRTU RopeSensorsCom = new COM_ModbusRTU("COM4");
        COM_ModbusRTU LaserCom = new COM_ModbusRTU("COM3", 115200);
        COM_ModbusRTU TempCom;
        bool ContinueReadFlag = false;
        private void btn_searchcom_Click(object sender, EventArgs e)
        {
            //直接用datasource属性
            cmb_avaiCom.DataSource = SerialPort.GetPortNames();

            //string[] portNames = SerialPort.GetPortNames();
            //foreach (string portName in portNames)
            //{
            //    cmb_avaiCom.Items.Add(portName);
            //}

        }

        private void btn_connectcom_Click(object sender, EventArgs e)
        {
            try
            {
                RopeSensorsCom.Close();
                LaserCom.Close();

                TempCom = new COM_ModbusRTU(cmb_avaiCom.Text);


                TempCom.Open();
                //初始化单台测试从站号
                cmb_slaveNum.SelectedIndex = 1;
                //初始化多台机数据表格
                dgv_SensorV.Rows.Clear();
                dgv_SensorV.Rows.Add("1", "0"); dgv_SensorV.Rows.Add("2", "0"); dgv_SensorV.Rows.Add("3", "0");
                dgv_SensorV.Rows.Add("4", "0"); dgv_SensorV.Rows.Add("5", "0"); dgv_SensorV.Rows.Add("6", "0");
                dgv_SensorV.Rows.Add("7", "0");

                MessageBox.Show("连接成功！");
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_readSlaveNum_Click(object sender, EventArgs e)
        {
            try
            {
                byte slaveNum = Convert.ToByte(cmb_slaveNum.SelectedIndex + 1);
                //读取0000 0001两寄存器为计数值(int32),前者为高位，后者为低位
                ushort[] ushorts = TempCom.ReadRegisters(slaveNum, 0, 2);
                int Value = TempCom.ConvertToInt(ushorts[0], ushorts[1]);
                float sensorValue = (float)Value / 1000;
                txb_receiveCOM.AppendText(DateTime.Now.ToString("T") + $": Sensor{slaveNum} {sensorValue.ToString()}" + " \r\n");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_CloseCom_Click(object sender, EventArgs e)
        {
            if (TempCom != null)
            {
                TempCom.Close();
            }

        }

        private void btn_readValues_Click(object sender, EventArgs e)
        {
            try
            {
                //循环读取自定义个位置传感器的值，显示DGV上
                Int16 slaveNum = Convert.ToInt16(cmb_slaveCount.Text);
                ContinueReadFlag = true;
                Task.Run(() =>
                {

                    while (ContinueReadFlag)
                    {
                        if (TempCom.portOpen)
                        {


                            int[] values = TempCom.ReadAllSlaveData((ushort)slaveNum);

                            DisplayDataInDGV(values);
                        }

                        Thread.Sleep(5); // 轮询周期
                    }
                });



            }
            catch (Exception ex)
            {
                ContinueReadFlag = false;
                MessageBox.Show(ex.ToString());
            }
        }
        private void DisplayDataInDGV(int[] DataArray, double Scale = 0.001)
        {
            if (DataArray.Length > 7)
            {
                RunLogMessage("传感器个数错误");
                return;
            }

            if (dgv_SensorV.InvokeRequired)
            {
                dgv_SensorV.Invoke(new Action(() =>
                {

                    // 按顺序将 uint 数组元素添加到 DGV 的第二列
                    for (int i = 0; i < DataArray.Length; i++)
                    {
                        dgv_SensorV.Rows[i].Cells[1].Value = DataArray[i] * Scale;
                    }
                }));
            }
            else
            {
                // 按顺序将 uint 数组元素添加到 DGV 的第二列
                for (int i = 0; i < DataArray.Length; i++)
                {
                    dgv_SensorV.Rows[i].Cells[1].Value = DataArray[i] * Scale;
                }
            }
        }

        private void btn_StopRead_Click(object sender, EventArgs e)
        {
            ContinueReadFlag = false;
        }
        #endregion


        #region  【IO测试】
        private void btn_initboar_Click(object sender, EventArgs e)
        {
            alignControl.boardInit();
        }

        private void btn_closeBoar_Click(object sender, EventArgs e)
        {
            alignControl.boardClose();

        }
        int currentOutState;
        private void cmb_Outnum_SelectedIndexChanged(object sender, EventArgs e)
        {
            int CurrenOutNum = Convert.ToInt32(cmb_Outnum.Text);
            try
            {
                currentOutState = Dmc1000.d1000_get_outbit(CurrenOutNum);
                if (currentOutState == 0)
                {
                    rbt_LowOut.Checked = true;
                    rbt_HighOut.Checked = false;
                }
                else if (currentOutState == 1)
                {
                    rbt_LowOut.Checked = false;
                    rbt_HighOut.Checked = true;
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }



        }

        private void btn_changeState_Click(object sender, EventArgs e)
        {
            try
            {
                int CurrenOutNum = Convert.ToInt32(cmb_Outnum.Text);
                if (currentOutState == 0)
                {
                    Dmc1000.d1000_out_bit(CurrenOutNum, 1);

                }
                else if (currentOutState == 1)
                {
                    Dmc1000.d1000_out_bit(CurrenOutNum, 0);

                }
                currentOutState = Dmc1000.d1000_get_outbit(CurrenOutNum);
                if (currentOutState == 0)
                {
                    rbt_LowOut.Checked = true;
                    rbt_HighOut.Checked = false;
                }
                else if (currentOutState == 1)
                {
                    rbt_LowOut.Checked = false;
                    rbt_HighOut.Checked = true;
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void cmb_Innum_SelectedIndexChanged(object sender, EventArgs e)
        {
            int CurrenInNum = Convert.ToInt32(cmb_Innum.Text);
            try
            {
                int currentInState = Dmc1000.d1000_in_bit(CurrenInNum);
                if (currentInState == 0)
                {
                    rbt_LowIn.Checked = true;
                    rbt_HighIn.Checked = false;
                }
                else if (currentInState == 1)
                {
                    rbt_LowIn.Checked = false;
                    rbt_HighIn.Checked = true;
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_readIn_Click(object sender, EventArgs e)
        {

            int CurrenInNum = Convert.ToInt32(cmb_Innum.Text);
            try
            {
                int currentInState = Dmc1000.d1000_in_bit(CurrenInNum);
                if (currentInState == 0)
                {
                    rbt_LowIn.Checked = true;
                    rbt_HighIn.Checked = false;
                }
                else if (currentInState == 1)
                {
                    rbt_LowIn.Checked = false;
                    rbt_HighIn.Checked = true;
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }

        private void btn_playsound1_Click(object sender, EventArgs e)
        {
            try
            {
                SoundPlayer player = new SoundPlayer();
                player.SoundLocation = @"D:\粤水电\对准完成，请开始焊接.wav";
                player.Load(); //同步加载声音
                player.Play(); //启用新线程播放
            }
            catch (Exception)
            {

                throw;
            }


        }
        #endregion


        #region 【组队控制界面】

        #region 组队滚轮架
        AligningControl alignControl = new AligningControl();
        private bool camera_Run;

        private void btn_MoveIn1_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunPosit();

        }

        private void btn_MoveIn1_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunPosit();
        }

        private void btn_MoveOut1_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunNegat();
        }
        private void btn_MoveOut1_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunNegat();
        }


        private void btn_MoveIn2_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel2.StartRunPosit();
        }

        private void btn_MoveIn2_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel2.StopRunPosit();

        }

        private void btn_MoveOut2_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel2.StartRunNegat();
        }

        private void btn_MoveOut2_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel2.StopRunNegat();
        }

        private void btn_MoveIn3_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel3.StartRunPosit();
        }

        private void btn_MoveIn3_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel3.StopRunPosit();

        }

        private void btn_MoveOut3_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel3.StartRunNegat();
        }

        private void btn_MoveOut3_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel3.StopRunNegat();

        }

        private void btn_MoveIn4_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel4.StartRunPosit();
        }

        private void btn_MoveIn4_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel4.StopRunPosit();
        }

        private void btn_MoveOut4_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel4.StartRunNegat();
        }

        private void btn_MoveOut4_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel4.StopRunNegat();

        }

        private void btn_JackLeft_MouseDown(object sender, MouseEventArgs e)
        {
            JackRightLeft.StartRunPosit();
        }

        private void btn_JackLeft_MouseUp(object sender, MouseEventArgs e)
        {
            JackRightLeft.StopRunPosit();

        }

        private void btn_JackRight_MouseDown(object sender, MouseEventArgs e)
        {
            JackRightLeft.StartRunNegat();
        }

        private void btn_JackRight_MouseUp(object sender, MouseEventArgs e)
        {
            JackRightLeft.StopRunNegat();
        }

        private void btn_JackUp_MouseDown(object sender, MouseEventArgs e)
        {
            JackUpDown.StartRunPosit();
        }

        private void btn_JackUp_MouseUp(object sender, MouseEventArgs e)
        {
            JackUpDown.StopRunPosit();
        }

        private void btn_JackDown_MouseDown(object sender, MouseEventArgs e)
        {
            JackUpDown.StartRunNegat();
        }

        private void btn_JackDown_MouseUp(object sender, MouseEventArgs e)
        {
            JackUpDown.StopRunNegat();
        }
        #endregion

        #region 后方滚轮架


        private void btn_StartStopRunB_Click(object sender, EventArgs e)
        {
            try
            {
                if (alignControl.RunflagB)
                {

                    alignControl.RunStopB();

                }
                else
                {
                    alignControl.RunStartB();

                }
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }
        private void btn_Runmodel_Click(object sender, EventArgs e)
        {
            try
            {

                if (alignControl.RunModelB == 1)
                {
                    alignControl.TurnSpinState();

                }
                else if (alignControl.RunModelB == 2)
                {
                    alignControl.TurnMoveState();

                }
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }
        private void btn_SpinUp_Click(object sender, EventArgs e)
        {
            try
            {
                switch (alignControl.SpinstateB)
                {
                    case 0://未运行
                        alignControl.SpinUpStart();

                        break;
                    case 1:
                        alignControl.SpinUpStop();


                        break;

                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }






        private void btn_MovePositive_Click(object sender, EventArgs e)
        {
            switch (alignControl.MovestateB)
            {
                case 0://未运行
                    alignControl.MovePosiStart();

                    break;
                case 1:
                    alignControl.MovePosiStop();


                    break;

            }
        }

        private void btn_MoveNegative_Click(object sender, EventArgs e)
        {
            switch (alignControl.MovestateB)
            {
                case 0://未运行
                    alignControl.MoveNegaStart();

                    break;
                case 2:
                    alignControl.MoveNegaStop();


                    break;

            }
        }

        private void btn_SpinDown_Click(object sender, EventArgs e)
        {
            switch (alignControl.SpinstateB)
            {
                case 0://未运行
                    alignControl.SpinDownStart();

                    break;
                case 2:
                    alignControl.SpinDownStop();


                    break;

            }
        }
        private void btn_SpeedUp_Click(object sender, EventArgs e)
        {
            alignControl.SpeedUp();
        }
        private void btn_SpeedDown_Click(object sender, EventArgs e)
        {
            alignControl.SpeedDown();
        }

        #endregion

        #endregion

        #region【回零操作】

        public void AllStopRun()
        {
            Wheel1.AllStop();
            Wheel2.AllStop();
            Wheel3.AllStop();
            Wheel4.AllStop();
            JackRightLeft.AllStop();
            JackUpDown.AllStop();
            alignControl.RunStopB();
            alignControl.stoprunH();
            RunLogMessage("软件系统停止运行");
        }
        private void btn_AllWheelsHome_Click(object sender, EventArgs e)
        {
            try
            {
                AllWheelZero();


            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }
        private void btn_AllStop_Click(object sender, EventArgs e)
        {
            AllStopRun();
        }

        private void AllWheelZero()
        {
            //4滚轮同时进行回零
            Task RunZ1 = new Task(() => { WheelToZero(1); });
            Task RunZ2 = new Task(() => { WheelToZero(2); });
            Task RunZ3 = new Task(() => { WheelToZero(3); });
            Task RunZ4 = new Task(() => { WheelToZero(4); });

            RunZ1.Start(); RunZ2.Start(); RunZ3.Start(); RunZ4.Start();
        }
        private void AllJackZero()
        {
            //千斤顶回零
            Task RunZ5 = new Task(() => { JackToZero(5); });
            Task RunZ6 = new Task(() => { JackToZero(6); });

            RunZ5.Start();
            RunZ6.Start();
        }



        public int WheelToZero(int ID)
        {
            if (ID > 4 | ID < 1)
            {
                MessageBox.Show($"轮{ID};轮号错误");
                return -1;
            }
            if (!alignControl.ControlInit)
            {
                MessageBox.Show($"轮{ID};板卡a未初始化！回零已停止");
                return -1;
            }
            if (!RopeSensorsCom.portOpen)
            {
                MessageBox.Show($"轮{ID};传感器未初始化！回零已停止");
                return -1;
            }
            if (!alignControl.RunFlagH)
            {
                MessageBox.Show($"轮{ID}:组队液压站未启动！回零已停止");
                return -1;
            }
            int sensorIndex = ID - 1;
            string headstr = "回零:";
            try
            {

                //回零信号启动
                wheels[sensorIndex].GoZeroFlag = true;
                RunLogMessage(headstr + $"轮{ID}回零标志开启");
                wheels[sensorIndex].SoftLimitNFlag = false;
                //连续反向移动，直到对应零位开关触发，停止，记录此时拉绳值，并想内移动到初始位
                wheels[sensorIndex].StartRunNegat();
                RunLogMessage(headstr + $"轮{ID}开始回零");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool ask = true;
                while (ask)
                {
                    int re = Dmc1000.d1000_in_bit(wheels[sensorIndex].ZeroInNum);
                    if (re == 0)
                    {
                        RunLogMessage(headstr + $"轮{ID}已在零点位，开始等待");
                        wheels[sensorIndex].StopRunNegat();
                        wheels[sensorIndex].IsOnZero = true;
                        ask = false;

                    }
                    Thread.Sleep(5);
                    if (stopwatch.ElapsedMilliseconds > 120000)
                    {
                        RunLogMessage(headstr + $"轮{ID}回零超时，请检查IO！");
                        wheels[sensorIndex].StopRunNegat();
                        ask = false;
                        stopwatch.Stop();
                        return -2;
                    }

                }
                //持续等待至4个轮位零信号位true
                Stopwatch stopwatch2 = new Stopwatch();
                stopwatch2.Start();
                bool ask2 = true;
                bool allzero = true;
                while (ask2)
                {
                    allzero = true;
                    foreach (var wheel in wheels)
                    {
                        allzero = allzero && wheel.IsOnZero;
                    }
                    if (allzero)
                    {
                        RunLogMessage(headstr + $"4轮已全部位零，轮{ID}开始返回初始位");
                        ask2 = false;

                    }

                    if (stopwatch2.ElapsedMilliseconds > 30000)
                    {
                        RunLogMessage(headstr + $"轮{ID}等待超时，请检查其他轮状态！");

                        ask2 = false;
                        stopwatch.Stop();
                        return -2;
                    }
                    Thread.Sleep(5);

                }
                //延时以保证其他轮识别到全回零
                Thread.Sleep(500);
                //回零位false
                wheels[sensorIndex].IsOnZero = false;
                //huoqu当前位置为原点位
                wheels[sensorIndex].ZeroPos = wheels[sensorIndex].OriginPosition;
                //开始正向移动到初始位
                int waittime = 3000;
                //反向移动等待
                int waittimeback = 1000;
                if (ID < 3)//前两轮主动等待
                {
                    Thread.Sleep(waittime);
                    wheels[sensorIndex].MoveToPos(-150);
                    Thread.Sleep(waittime);
                    wheels[sensorIndex].MoveToPos(-100);
                    Thread.Sleep(waittime);
                    wheels[sensorIndex].MoveToPos(-50);
                    Thread.Sleep(waittime);
                    wheels[sensorIndex].MoveToPos(0);
                }
                else
                {
                    //反向移动1秒
                    wheels[sensorIndex].StartRunNegat();
                    Thread.Sleep(waittimeback);
                    wheels[sensorIndex].StopRunNegat();
                    Thread.Sleep(waittimeback / 10);
                    wheels[sensorIndex].MoveToPos(0);
                }


                RunLogMessage(headstr + $"轮{ID}已到达初始位，回零完成");

                wheels[sensorIndex].GoZeroFlag = false;
                RunLogMessage(headstr + $"轮{ID}回零标志关闭");
                return 0;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                wheels[sensorIndex].GoZeroFlag = false;
                return -1;
            }



        }

        public int JackToZero(int AxisID)
        {
            if (AxisID > 6 | AxisID < 5)
            {
                MessageBox.Show($"千斤顶ID错误");
                return -1;
            }
            if (!alignControl.ControlInit)
            {
                MessageBox.Show($"千斤顶{AxisID};板卡a未初始化！回零已停止");
                return -1;
            }
            if (!RopeSensorsCom.portOpen)
            {
                MessageBox.Show($"千斤顶{AxisID};传感器未初始化！回零已停止");
                return -1;
            }
            if (!alignControl.RunFlagH)
            {
                MessageBox.Show($"千斤顶{AxisID}:组队液压站未启动！回零已停止");
                return -1;
            }
            int sensorIndex = AxisID - 5;   //轮ID为5、6，其索引为0、1
            try
            {

                //回零信号启动
                Jacks[sensorIndex].GoZeroFlag = true;
                RunLogMessage($"千斤顶{AxisID}回零标志开启");
                Jacks[sensorIndex].SoftLimitNFlag = false;
                //连续反向移动，直到对应零位开关触发，停止，记录此时拉绳值，并想内移动到初始位
                Jacks[sensorIndex].StartRunNegat();
                RunLogMessage($"千斤顶{AxisID}开始回零");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool ask = true;
                while (ask)
                {
                    int re = Dmc1000.d1000_in_bit(Jacks[sensorIndex].ZeroInNum);
                    if (re == 0)
                    {
                        RunLogMessage($"千斤顶{AxisID}已在零点位");
                        Jacks[sensorIndex].StopRunNegat();
                        Jacks[sensorIndex].IsOnZero = true;
                        ask = false;

                    }
                    Thread.Sleep(5);
                    if (stopwatch.ElapsedMilliseconds > 60000)
                    {
                        RunLogMessage($"千斤顶{AxisID}回零超时，请检查IO！");
                        Jacks[sensorIndex].StopRunNegat();
                        ask = false;
                        stopwatch.Stop();
                        return -2;
                    }

                }

                Thread.Sleep(1000);

                //huoqu当前位置为原点位
                Jacks[sensorIndex].ZeroPos = Jacks[sensorIndex].OriginPosition;
                //开始正向移动到初始位
                Jacks[sensorIndex].MoveToPos(0);
                RunLogMessage($"千斤顶{AxisID}已到达初始位，回零完成");

                Jacks[sensorIndex].GoZeroFlag = false;
                RunLogMessage($"千斤顶{AxisID}回零标志关闭");
                return 0;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                Jacks[sensorIndex].GoZeroFlag = false;
                return -1;
            }



        }

        private void btn_wheelsTozero_Click(object sender, EventArgs e)
        {
            Task.Run(() => Wheel1.MoveToPos(0));
            Task.Run(() => Wheel2.MoveToPos(0));
            Task.Run(() => Wheel3.MoveToPos(0));
            Task.Run(() => Wheel4.MoveToPos(0));
        }

        private void btn_wheel2Tozero_Click(object sender, EventArgs e)
        {
            if (DialogResult.Yes == MessageBox.Show(this, "请谨慎核对：当前组队机是否搭载塔筒？\r", "安全性确认", MessageBoxButtons.YesNo))
            {
                MessageBox.Show("禁止回零！");
                return;
            }
            Task RunZ2 = new Task(() => { WheelToZero(2); });
            RunZ2.Start();

        }

        private void btn_wheel3Tozero_Click(object sender, EventArgs e)
        {
            if (DialogResult.Yes == MessageBox.Show(this, "请谨慎核对：当前组队机是否搭载塔筒？\r", "安全性确认", MessageBoxButtons.YesNo))
            {
                MessageBox.Show("禁止回零！");
                return;
            }
            Task RunZ3 = new Task(() => { WheelToZero(3); });
            RunZ3.Start();

        }

        private void btn_wheel4Tozero_Click(object sender, EventArgs e)
        {
            if (DialogResult.Yes == MessageBox.Show(this, "请谨慎核对：当前组队机是否搭载塔筒？\r", "安全性确认", MessageBoxButtons.YesNo))
            {
                MessageBox.Show("禁止回零！");
                return;
            }
            Task RunZ4 = new Task(() => { WheelToZero(4); });
            RunZ4.Start();

        }

        private void btn_JackHome_Click(object sender, EventArgs e)
        {

            AllJackZero();
        }

        private void btn_JackTozero_Click(object sender, EventArgs e)
        {

            Task.Run(() => JackRightLeft.MoveToPos(0));
            Task.Run(() => JackUpDown.MoveToPos(0));

        }
        #endregion

        #region【后台状态读取】
        /// <summary>
        /// 读取到6拉绳原始数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bgw_Readsensors_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                //分多个任务
                Task.Run(() =>
                {
                    while (true)
                    {

                        //读取6拉绳数值
                        if (!RopeSensorsCom.portOpen)
                        {
                            continue;
                        }
                        //循环处理位置，保存
                        for (int i = 0; i < 4; i++)
                        {

                            wheels[i].OriginPosition = RopeSensorsCom.ReadSingleSlaveData(wheels[i].ID) / 1000;//从机地址1开始
                                                                                                               //RunLogMessage($"读取拉绳{i + 1},原始值{wheels[i].OriginPosition}");
                                                                                                               //立马检查当前位置是否超软限位

                            if (wheels[i].CurrentPosition > wheels[i].SoftLimitP & !wheels[i].GoZeroFlag)//回零过程不判定软限位
                            {
                                wheels[i].StopRunPosit();
                                wheels[i].SoftLimitPFlag = true;
                            }
                            else
                            {
                                wheels[i].SoftLimitPFlag = false;
                            }
                            if (wheels[i].CurrentPosition < wheels[i].SoftLimitN & !wheels[i].GoZeroFlag)
                            {
                                wheels[i].StopRunNegat();

                                wheels[i].SoftLimitNFlag = true;
                            }
                            else
                            {
                                wheels[i].SoftLimitNFlag = false;
                            }


                        }


                        Thread.Sleep(5);

                    }
                });
                //读取激光，保存
                Task.Run(() =>
                {
                    while (true)
                    {
                        PublicValue.LaserPos = LaserCom.ReadSingleSlaveData(1);

                        Thread.Sleep(5);
                    }
                });


            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
        }
        private void bgw_HardLimitState_DoWork(object sender, DoWorkEventArgs e)
        {

            //触发硬限位进行停止操作


            try
            {
                while (true)
                {
                    Thread.Sleep(100);
                    if (SoftEmergencyFlag)
                    {
                        AllStopRun();
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());

            }



        }

        private void timer_UpdateCamWin_Tick(object sender, EventArgs e)
        {



            //更新显示错边、间隙
            //位置1
            if (Math.Abs(DispHeightDis1) > HeightDisMax)
            {
                txb_DisHeight1.ForeColor = Color.Red;
            }
            else
            {
                txb_DisHeight1.ForeColor = Color.Lime;
            }
            if (DispGap1 > GapDisMax)
            {
                txb_DisWidth1.ForeColor = Color.Red;
            }
            else
            {
                txb_DisWidth1.ForeColor = Color.Lime;
            }


            txb_DisHeight1.Text = DispHeightDis1.ToString("F2");
            txb_DisWidth1.Text = DispGap1.ToString("F2");

            if (Math.Abs(DispHeightDis1) > HeightDisMax | DispGap1 > GapDisMax)
            {
                pbx_State1.Image = abnormalPic;

            }
            else
            {
                pbx_State1.Image = finePic;
            }


            //位置2
            if (Math.Abs(DispHeightDis2) > HeightDisMax)
            {
                txb_DisHeight2.ForeColor = Color.Red;
            }
            else
            {
                txb_DisHeight2.ForeColor = Color.Lime;
            }
            if (DispGap2 > GapDisMax)
            {
                txb_DisWidth2.ForeColor = Color.Red;
            }
            else
            {
                txb_DisWidth2.ForeColor = Color.Lime;
            }


            txb_DisHeight2.Text = DispHeightDis2.ToString("F2");
            txb_DisWidth2.Text = DispGap2.ToString("F2");

            if (Math.Abs(DispHeightDis2) > HeightDisMax | DispGap2 > GapDisMax)
            {
                pbx_State2.Image = abnormalPic;

            }
            else
            {
                pbx_State2.Image = finePic;
            }
            //位置3
            if (Math.Abs(DispHeightDis3) > HeightDisMax)
            {
                txb_DisHeight3.ForeColor = Color.Red;
            }
            else
            {
                txb_DisHeight3.ForeColor = Color.Lime;
            }
            if (DispGap3 > GapDisMax)
            {
                txb_DisWidth3.ForeColor = Color.Red;
            }
            else
            {
                txb_DisWidth3.ForeColor = Color.Lime;
            }


            txb_DisHeight3.Text = DispHeightDis3.ToString("F2");
            txb_DisWidth3.Text = DispGap3.ToString("F2");

            if (Math.Abs(DispHeightDis3) > HeightDisMax | DispGap3 > GapDisMax)
            {
                pbx_State3.Image = abnormalPic;

            }
            else
            {
                pbx_State3.Image = finePic;
            }


            if (CurrentProfile[0] != null)
            {
                if (CurrentProfile[0].Length != 0)
                {


                    ProfileProcess.Profile2bmp(CurrentProfile[0], CatchPart, 1000, out Bitmap bitmap1);
                    HObject hObject = PublicFuntions.ConvertBitmapToHObject(bitmap1);
                    PublicFuntions.DispImage(hObject, hWindowControl1.HalconWindow);
                }
            }
            if (CurrentProfile[1] != null)
            {
                if (CurrentProfile[1].Length != 0)
                {
                    ProfileProcess.Profile2bmp(CurrentProfile[1], CatchPart, 1000, out Bitmap bitmap2);
                    HObject hObject2 = PublicFuntions.ConvertBitmapToHObject(bitmap2);
                    PublicFuntions.DispImage(hObject2, hWindowControl2.HalconWindow);
                }
            }
            if (CurrentProfile[2] != null)
            {
                if (CurrentProfile[2].Length != 0)
                {
                    ProfileProcess.Profile2bmp(CurrentProfile[2], CatchPart, 1000, out Bitmap bitmap2);
                    HObject hObject2 = PublicFuntions.ConvertBitmapToHObject(bitmap2);
                    PublicFuntions.DispImage(hObject2, hWindowControl3.HalconWindow);
                }
            }



        }

        private void bgw_ReadCams_DoWork(object sender, DoWorkEventArgs e)
        {
            if (CamControl7400_2.Connected != 1)
            {
                RunLogMessage($"开启读取失败,控制器{CamControl7400_2.ID}未连接");
                return;
            }

            //读取2个线激光
            try
            {
                bool readfalg = true;
                Stopwatch stopwatch = new Stopwatch();
                while (readfalg)
                {
                    //采集轮廓+处理输出数据+输出图像

                    stopwatch.Restart();
                    int[] Profile;
                    uint[] _EncoderData;
                    if (CamControl7400_2.GetProfile(out Profile, out _EncoderData) == 0)
                    {
                        //暂定
                        int[] ProfileA = Profile.Take(3200).ToArray();
                        int[] ProfileB = Profile.Skip(3200).Take(Profile.Length - 3200).ToArray();

                        if (ProfileA.Length >= CatchPart)
                        {
                            ProfileProcess.FindNumsByPlatforms(ProfileA, CatchPart, VariWindowWidth, VariThreshold, 10, 0.09, out double heightDis, out double gap);
                            DispGap2 = gap;
                            DispHeightDis2 = heightDis;
                        }
                        if (ProfileB.Length >= CatchPart)
                        {
                            ProfileProcess.FindNumsByPlatforms(ProfileB, CatchPart, VariWindowWidth, VariThreshold, 10, 0.09, out double heightDis, out double gap);
                            DispGap3 = gap;
                            DispHeightDis3 = heightDis;
                        }

                        CurrentProfile[1] = ProfileA;
                        CurrentProfile[2] = ProfileB;
                        //测试处理一个相机3ms左右
                    }
                    else
                    {
                        readfalg = false;
                        RunLogMessage("获取轮廓失败，请检查批处理模式是否关闭");
                        PublicValue.APPstatus = (int)PublicValue.APPstatusE.手动;
                    }




                    Thread.Sleep(10);

                }




            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }




        }


        private void bgw_ReadCams3_DoWork(object sender, DoWorkEventArgs e)
        {
            if (CamControl7900.Connected != 1)
            {
                RunLogMessage($"开启读取失败,控制器{CamControl7400_2.ID}未连接");
                return;
            }

            //读取1个线激光
            try
            {
                Stopwatch stopwatch = new Stopwatch();
                bool readfalg = true;
                while (readfalg)
                {
                    //采集轮廓+处理输出数据+输出图像

                    stopwatch.Restart();
                    int[] Profile;
                    uint[] _EncoderData;
                    if (CamControl7900.GetProfile(out Profile, out _EncoderData) == 0)
                    {
                        //暂定
                        int[] ProfileA = Profile.Take(3200).ToArray();
                        int[] ProfileB = Profile.Skip(3200).Take(Profile.Length - 3200).ToArray();


                        ProfileProcess.FindNumsByPlatforms(ProfileA, CatchPart, VariWindowWidth, VariThreshold, 10, 0.18, out double heightDis, out double gap);
                        DispGap1 = gap;
                        //因为7900与7400摆放方向相反，错边值相反
                        DispHeightDis1 = -heightDis;



                        CurrentProfile[0] = ProfileA;



                    }
                    else
                    {
                        readfalg = false;
                        RunLogMessage("获取轮廓失败，请检查批处理模式是否关闭");
                        PublicValue.APPstatus = (int)PublicValue.APPstatusE.手动;
                    }




                    Thread.Sleep(5);

                }




            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }

        }
        #endregion

        #region【组队流程控制逻辑】
        //4滚轮控制逻辑

        /// <summary>
        /// 根据左右两边间隙，同时左右移动前2滚轮，矫正绕Z轴的旋转
        /// </summary>
        /// <param name="DeffThreshold">允许的最终两边间隙差值</param>
        /// <param name="Outtime">耗时超时</param>
        public void CorrectRotaZ(double DeffThreshold, int Outtime, double moveUnit)
        {
            if (moveUnit < 1)
            {
                RunLogMessage("移动单元过小，已停止");
                return;
            }

            string headMes = "【对准环节】：";

            if (DispGap1 > DispGap2 & Math.Abs(DispGap1 - DispGap2) > DeffThreshold)//左边大于右边一定程度，前2轮往左移，1轮外移，2轮内移
            {


                RunLogMessage(headMes + $"检测到左侧1号线激光间隙大于右侧2号，开始向向左移动12滚轮");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //先移动左边轮，向左，为负
                    Wheel1.MoveToPosRelatively(-moveUnit);
                    //在移动右边轮，向左，为正
                    Wheel2.MoveToPosRelatively(moveUnit);

                    ////先右移4轮，为负
                    //Wheel4.MoveToPosRelatively(-moveUnit);
                    ////后右移3轮，为正
                    //Wheel3.MoveToPosRelatively(moveUnit);

                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"向左移动12滚轮超时，已停止");
                        monitorStart = false;
                    }
                    if (Math.Abs(DispGap1 - DispGap2) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"两边间隙调整完成，当前间隙差{Math.Abs(DispGap1 - DispGap2)}mm；耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;


                    }
                    else if (DispGap1 < DispGap2 & Math.Abs(DispGap1 - DispGap2) > DeffThreshold)
                    {

                        monitorStart = false;
                        RunLogMessage(headMes + $"调整过度，右边间隙已大于左边，移动单元减半为{moveUnit / 2},开始下一轮判定调整，当前间隙差{Math.Abs(DispGap1 - DispGap2)}mm");
                        //停止后，再次循环
                        CorrectRotaZ(DeffThreshold, Outtime, moveUnit / 2);

                    }


                    Thread.Sleep(50);
                }


            }
            else if (DispGap1 < DispGap2 & Math.Abs(DispGap1 - DispGap2) > DeffThreshold)//相反右边大于左边一定程度，则12轮向右移，1轮内移，2轮外移
            {

                RunLogMessage(headMes + $"检测到右侧2号线激光间距大于左侧1号，开始向右移动12滚轮");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //右轮先移动，向右，为负
                    Wheel2.MoveToPosRelatively(-moveUnit);
                    //左轮后移动，向右，为正
                    Wheel1.MoveToPosRelatively(moveUnit);

                    ////先左移3轮，为负
                    //Wheel3.MoveToPosRelatively(-moveUnit);
                    ////后左移4轮，为正
                    //Wheel4.MoveToPosRelatively(moveUnit);


                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"向右移动12滚轮超时，已停止");
                        monitorStart = false;
                    }
                    if (Math.Abs(DispGap1 - DispGap2) < DeffThreshold)
                    {

                        monitorStart = false;
                        RunLogMessage(headMes + $"RZ矫正完成，当前间隙差{Math.Abs(DispGap1 - DispGap2)}mm；耗时{stopwatch.ElapsedMilliseconds}ms");

                    }
                    else if (DispGap1 > DispGap2 & Math.Abs(DispGap1 - DispGap2) > DeffThreshold)
                    {

                        monitorStart = false;
                        RunLogMessage(headMes + $"RZ调整过度，左边间隙已大于右边；移动单元减半为{moveUnit / 2},开始下一轮判定调整，当前间隙差{Math.Abs(DispGap1 - DispGap2)}mm");
                        //停止后，再次循环
                        CorrectRotaZ(DeffThreshold, Outtime, moveUnit / 2);

                    }
                    Thread.Sleep(50);
                }

            }
            else
            {
                RunLogMessage(headMes + $"左右间隙接近，RZ无需矫正");
            }


        }
        /// <summary>
        /// 调整左侧与底部间隙差，矫正RY
        /// </summary>
        /// <param name="DeffThreshold">允许的误差</param>
        /// <param name="Outtime">超时耗时</param>
        public void CorrectRotaY(double DeffThreshold, int Outtime, double moveUnit)
        {
            //if (Math.Abs(DispGap1 - DispGap2) > DeffThreshold)
            //{
            //    RunLogMessage("两侧间隙不一致，RY矫正已停止！");
            //}
            if (moveUnit < 1)
            {
                RunLogMessage("移动单元过小，已停止");
                return;
            }
            string headMes = "【对准环节】：";
            //若焊接面翘起
            if ((DispGap1 + DispGap2) / 2 > DispGap3 & Math.Abs((DispGap1 + DispGap2) / 2 - DispGap3) > DeffThreshold)//左边大于底部一定程度，1轮内移，2轮内移
            {



                RunLogMessage(headMes + $"检测到底部线激光间距偏小，12轮开始收缩");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    Thread.Sleep(500);
                    //12轮收缩
                    Wheel1.MoveToPosRelatively(moveUnit);
                    Wheel2.MoveToPosRelatively(moveUnit);



                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"移动12滚轮超时，已停止");
                        monitorStart = false;
                    }
                    if (Math.Abs((DispGap1 + DispGap2) / 2 - DispGap3) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正RY已完成，当前左右与底边间隙差{Math.Abs((DispGap1 + DispGap2) / 2 - DispGap3)}");
                        monitorStart = false;
                    }
                    else if ((DispGap1 + DispGap2) / 2 < DispGap3 & Math.Abs((DispGap1 + DispGap2) / 2 - DispGap3) > DeffThreshold)
                    {

                        RunLogMessage(headMes + $"调整过度，左右间隙已小于底边，移动单元减半为{moveUnit / 2},开始下一轮判定调整，当前间隙差{Math.Abs(DispGap1 - DispGap2)}mm");
                        monitorStart = false;
                        //停止后，再次循环
                        CorrectRotaY(DeffThreshold, Outtime, moveUnit / 2);

                    }


                }

            }
            //调整俯仰角这里有点不一样，中间必须大于底部，小于底部时没有允许空间
            else if ((DispGap1 + DispGap2) / 2 < DispGap3)//相反底部大于左边一定程度，则12轮向外移，1轮外移，2轮外移
            {

                RunLogMessage(headMes + $"检测到底部线激光间距偏大，12轮开始伸展");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    Thread.Sleep(500);
                    //后两轮伸展
                    Wheel1.MoveToPosRelatively(-moveUnit);
                    Wheel2.MoveToPosRelatively(-moveUnit);


                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"移动12滚轮超时，已停止");
                        monitorStart = false;

                    }
                    if (Math.Abs(DispGap1 - DispGap3) < DeffThreshold)
                    {
                        RunLogMessage(headMes + $"矫正RY已完成，当前13间隙差{Math.Abs(DispGap1 - DispGap3)}");
                        monitorStart = false;

                    }
                    else if ((DispGap1 + DispGap2) / 2 > DispGap3 & Math.Abs((DispGap1 + DispGap2) / 2 - DispGap3) > DeffThreshold)
                    {

                        monitorStart = false;
                        RunLogMessage(headMes + $"调整过度，左右间隙已大于底边，移动单元减半为{moveUnit / 2},开始下一轮判定调整，当前间隙差{Math.Abs(DispGap1 - DispGap2)}mm");

                        //停止后，再次循环
                        CorrectRotaY(DeffThreshold, Outtime, moveUnit / 2);

                    }
                }

            }
            else
            {
                RunLogMessage(headMes + $"左右间隙与底部间隙接近，RY无需矫正");
            }


        }
        /// <summary>
        /// 整体移动4滚轮，矫正Y方向
        /// </summary>
        /// <param name="DeffThreshold">允许误差</param>
        /// <param name="Outtime">耗时超时</param>
        /// 
        public void CorrectY(double DeffThreshold, int Outtime, double moveUnit)
        {
            //if (Math.Abs(DispGap1 - DispGap2) > DeffThreshold& Math.Abs(DispGap1 - DispGap3) > DeffThreshold)
            //{
            //    RunLogMessage("3处间隙不一致，Y向偏差矫正已停止！");
            //}
            if (moveUnit < 1)
            {
                RunLogMessage("移动单元过小，已停止");
                return;
            }

            string headMes = "【对准环节】：";
            //左边大于右边
            if (DispHeightDis1 > DispHeightDis2 & Math.Abs(DispHeightDis1 - DispHeightDis2) > DeffThreshold)//左边错边大于右边一定程度，4轮右移，1、3内，2、4外
            {//保证两边组队筒突出为正


                //按顺序


                RunLogMessage(headMes + $"检测到1线激光错边大于2线激光，四轮开始左移");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {

                    //两侧轮右移
                    //右侧轮先移动，右移为－

                    Wheel2.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    Wheel4.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    //左侧轮后移动，右移，为正

                    Wheel1.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);
                    Wheel3.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);




                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {


                        RunLogMessage(headMes + $"矫正Y偏差移动超时停止");
                        monitorStart = false;
                    }
                    if (Math.Abs(DispHeightDis1 - DispHeightDis2) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;
                    }
                    else if (DispHeightDis1 < DispHeightDis2 & Math.Abs(DispHeightDis1 - DispHeightDis2) > DeffThreshold)
                    {




                        RunLogMessage(headMes + $"矫正Y偏差过量，移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectY(DeffThreshold, Outtime, moveUnit / 2);

                    }
                    //每次整体移动后停止1秒
                    Thread.Sleep(1000);
                }

            }
            else if (DispHeightDis1 < DispHeightDis2 & Math.Abs(DispHeightDis1 - DispHeightDis2) > DeffThreshold)//相反右边大于左边一定程度，则1、3外移，2、4内移
            {


                RunLogMessage(headMes + $"检测到2线激光错边大于1线激光，四轮开始右移");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //两侧轮左移
                    //左侧轮先移动，左移为负
                    Wheel1.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    Wheel3.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);

                    //右侧轮后移动，左移为正
                    Wheel2.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);
                    Wheel4.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);





                    Thread.Sleep(10);
                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差移动超时停止");
                        monitorStart = false;

                    }
                    if (Math.Abs(DispHeightDis1 - DispHeightDis2) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;

                    }
                    else if (DispHeightDis1 > DispHeightDis2 & Math.Abs(DispHeightDis1 - DispHeightDis2) > DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差过量，耗时{stopwatch.ElapsedMilliseconds}ms,移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectY(DeffThreshold, Outtime, moveUnit / 2);

                    }
                    //每次整体移动后停止1秒
                    Thread.Sleep(1000);
                }

            }
            else
            {
                RunLogMessage(headMes + $"左右错边接近，Y无需矫正");
            }

        }
        /// <summary>
        /// 矫正Z向偏移
        /// </summary>
        /// <param name="DeffThreshold">允许误差</param>
        /// <param name="Outtime">超时耗时</param>
        public void CorrectZ(double DeffThreshold, int Outtime, double moveUnit)
        {
            //if (Math.Abs(DispGap1 - DispGap2) > DeffThreshold & Math.Abs(DispGap1 - DispGap3) > DeffThreshold)
            //{
            //    RunLogMessage("3处间隙不一致，Z向矫正已停止！");
            //}
            //if (Math.Abs(DispHeightDis1 - DispHeightDis2) > DeffThreshold )
            //{
            //    RunLogMessage("两边错边不一致，Z向矫正已停止！");
            //}

            if (moveUnit < 1)
            {
                RunLogMessage("移动单元过小，已停止");
                return;
            }


            string headMes = "【对准环节】：";
            //监测两边错边
            if (DispHeightDis3 > 0 & Math.Abs(DispHeightDis3 - 0) > DeffThreshold)//默认底部错边，组队边突出为正，此时将滚筒向上举升
            {


                RunLogMessage(headMes + $"检测到组对边底部偏低，四轮开始收缩抬升塔筒");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //收缩顺序：3-1-4-2
                    Wheel3.MoveToPosRelatively(moveUnit);
                    Wheel1.MoveToPosRelatively(moveUnit);
                    Wheel4.MoveToPosRelatively(moveUnit);
                    Wheel2.MoveToPosRelatively(moveUnit);


                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差超时，移动停止");
                        monitorStart = false;
                    }
                    if (Math.Abs(DispHeightDis3 - 0) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;
                    }
                    else if (DispHeightDis3 < 0 & Math.Abs(DispHeightDis3 - 0) > DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差过量，移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectZ(DeffThreshold, Outtime, moveUnit / 2);

                    }

                    Thread.Sleep(500);
                }

            }
            else if (DispHeightDis3 < 0 & Math.Abs(DispHeightDis3 - 0) > DeffThreshold)//组对边过高，两边外推
            {

                RunLogMessage(headMes + $"检测到组队边底部偏高，四轮开始伸展下降塔筒");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //伸展顺序：1-3-2-4
                    Wheel1.MoveToPosRelatively(-moveUnit);
                    Wheel3.MoveToPosRelatively(-moveUnit);
                    Wheel2.MoveToPosRelatively(-moveUnit);
                    Wheel4.MoveToPosRelatively(-moveUnit);




                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差超时，移动停止");
                        monitorStart = false;

                    }
                    if (Math.Abs(DispHeightDis3 - 0) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;

                    }
                    //万一移动停止不及时，超过
                    else if (DispHeightDis3 > 0 & Math.Abs(DispHeightDis3 - 0) > DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差过量，移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectY(DeffThreshold, Outtime, moveUnit / 2);

                    }
                    Thread.Sleep(500);
                }

            }
            else
            {
                RunLogMessage(headMes + $"底部间隙接近0，Z无需矫正");
            }

        }


        /// <summary>
        /// 拉近环节
        /// </summary>
        /// <param name="targetGap">目标间距,mm</param>
        /// <param name="Outtime">拉近超时</param>
        public void PullIn(int targetGap, double Outtime)
        {

            string headMes = "【拉近环节】：";
            //直接检测是否否大于20，都大于持续拉近，直到有一个小于//确保在只有一边时，gap值默认大于20
            if (DispGap1 > targetGap & DispGap2 > targetGap & DispGap3 > targetGap)
            {
                try
                {


                    alignControl.RunStartB();
                    alignControl.TurnMoveState();
                    alignControl.MovePosiStart();
                    RunLogMessage(headMes + $"检测到长间距，开始拉近后方滚轮架");
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    bool monitorStart = true;
                    int i = 0;
                    while (monitorStart)
                    {

                        //超时停止
                        if (stopwatch.ElapsedMilliseconds > Outtime)
                        {
                            alignControl.RunStopB();
                            monitorStart = false;
                            RunLogMessage(headMes + $"拉近超时停止");
                        }

                        if (DispGap1 < targetGap | DispGap2 < targetGap | DispGap3 < targetGap)
                        {
                            alignControl.RunStopB();
                            RunLogMessage(headMes + $"已检测到间距小于{targetGap}mm,拉近已完成");

                            monitorStart = false;
                        }

                        if (stopwatch.ElapsedMilliseconds > 5000 * i)
                        {
                            i++;
                            RunLogMessage(headMes + $"拉近中，请等待...");
                        }

                        Thread.Sleep(5);
                    }
                }
                catch (Exception ex)
                {

                    MessageBox.Show(ex.ToString());
                }
            }
            else
            {
                RunLogMessage(headMes + $"检测到间距较小，已无需自动拉近");
                return;
            }

        }
        /// <summary>
        /// 启用千斤顶后顶平，保持
        /// </summary>
        /// <param name="dis">与理论错边的允许差值</param>
        /// <param name="smooth">滚轮滑动+信号延时补偿距离</param>
        /// <param name="Outtime">超时时长，ms</param>
        public void QJDAction(double dis, double smooth, int Outtime)
        {

            //理论错边上限值
            double MaxDisCorrect = PublicValue.HeightDisCorrect + dis;
            //理论错边下限值
            double MinDisCorrect = PublicValue.HeightDisCorrect - dis;


            if (!alignControl.ControlInit) { MessageBox.Show("板卡未连接，请检查！"); return; }
            //先判断地3传感器错边高低，控制千斤顶移动到预先设定的位置；
            if (DispHeightDis3 >= MinDisCorrect & DispHeightDis3 <= MaxDisCorrect)
            {
                RunLogMessage($"底部错边满足要求，无需调整，千斤顶已停止，当前错边：{DispHeightDis3}mm");
                return;
            }
            else if (DispHeightDis3 > MaxDisCorrect)//默认大于上限为组队边突出，移动到近位置,//暂定，现场调整
            {
                JackRightLeft.MoveToPos(PublicValue.QJDPos[0]);
                RunLogMessage("开始在组队边顶升");
                //顶升，默认不在高位；直接顶；监控3先激光，持续顶起，直到错边到达指定值；
                JackUpDown.StartRunPosit();

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {
                        JackUpDown.StopRunPosit();
                        RunLogMessage("顶升超时,移动已停止");
                        monitorStart = false;
                    }

                    if (DispHeightDis3 < MaxDisCorrect + smooth & DispHeightDis3 > MinDisCorrect + smooth)
                    {
                        JackUpDown.StopRunPosit();
                        RunLogMessage("顶升已完成,可开始焊接");
                        monitorStart = false;
                    }


                    Thread.Sleep(5);
                }

            }
            else if (DispHeightDis3 < MinDisCorrect)
            {
                JackRightLeft.MoveToPos(PublicValue.QJDPos[1]);
                RunLogMessage("开始在移动边顶升");
                //顶升，默认不在高位；直接顶；监控3先激光，持续顶起，直到错边到达指定值；
                JackUpDown.StartRunPosit();

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {
                        JackUpDown.StopRunPosit();
                        RunLogMessage("顶升超时,移动已停止");
                        monitorStart = false;
                    }

                    if (DispHeightDis3 < MaxDisCorrect - smooth & DispHeightDis3 > MinDisCorrect - smooth)
                    {
                        JackUpDown.StopRunPosit();
                        RunLogMessage("顶升已完成,可开始焊接");
                        monitorStart = false;
                    }


                    Thread.Sleep(5);
                }
            }

        }

        public void MoveBack(int Outtime)
        {



        }





        private void bgw_StartCorrect_DoWork(object sender, DoWorkEventArgs e)
        {


            correct(0.5, 1.5, 3000);


        }


        /// <summary>
        /// 点焊错边矫正流程
        /// </summary>
        /// <param name="dis">与理论错边的允许差值</param>
        /// <param name="smooth">滚轮滑动+信号延时补偿距离</param>
        /// <param name="Outtime">超时时长，ms</param>
        public void correct(double dis, double smooth, double Outtime)
        {
            if (!alignControl.ControlInit) { MessageBox.Show("板卡未连接，请检查！"); return; }
            //允许与理论错边的差值


            //开始监测1号线激光，出现错边大于理论厝边，则同时移动焊接侧2轮内移动，直到错边在范围内；
            //理论错边上限值
            double MaxDisCorrect = PublicValue.HeightDisCorrect + dis;
            //理论错边下限值
            double MinDisCorrect = PublicValue.HeightDisCorrect - dis;

            string headMes = "【点焊环节】：";
            while (true)
            {

                if (DispHeightDis1 > MaxDisCorrect)//默认正值为组队边高于阈值，两轮内向移动
                {
                    //先停止旋转
                    alignControl.SpinUpStop();

                    //把界面控制旋转启停的按钮屏蔽
                    btn_StartStopSpin.Enabled = false;
                    RunLogMessage(headMes + "发现错边超限，旋转已自动停止，旋转控制已屏蔽");
                    Wheel1.StartRunPosit();
                    Wheel3.StartRunPosit();

                    RunLogMessage(headMes + "开始自动内顶矫正");
                    Outtime = 3000;
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    bool monitorStart = true;
                    while (monitorStart)
                    {
                        //超时停止
                        if (stopwatch.ElapsedMilliseconds > Outtime)
                        {
                            Wheel1.StopRunPosit();
                            Wheel3.StopRunPosit();
                            RunLogMessage(headMes + $"矫正超时，已停止；耗时{stopwatch.ElapsedMilliseconds}ms");
                            monitorStart = false;
                        }

                        if (MinDisCorrect + smooth < DispHeightDis1 & DispHeightDis1 < MaxDisCorrect + smooth)
                        {
                            Wheel1.StopRunPosit();
                            Wheel3.StopRunPosit();
                            RunLogMessage(headMes + $"矫正已完成，请继续焊接！耗时{stopwatch.ElapsedMilliseconds}ms");
                            monitorStart = false;
                        }
                        //若特殊情况直接小于最小允许值，则停止，再次判定
                        else if (DispHeightDis1 < MinDisCorrect)
                        {
                            Wheel1.StopRunPosit();
                            Wheel3.StopRunPosit();
                            RunLogMessage(headMes + $"矫正意外超过反向错边上限！已自动开始新一轮判定矫正；耗时{stopwatch.ElapsedMilliseconds}ms");
                            monitorStart = false;
                            Thread.Sleep(100);
                            correct(dis, smooth, Outtime);

                        }

                        Thread.Sleep(5);
                    }
                    //跳出循环后启动允许旋转，开启按钮
                    btn_StartStopSpin.Enabled = true;
                }
                //如果错边值开始低于最小允许
                else if (DispHeightDis1 < MinDisCorrect)
                {
                    //先停止旋转
                    alignControl.SpinUpStop();
                    //把界面控制旋转启停的按钮屏蔽
                    btn_StartStopSpin.Enabled = false;
                    RunLogMessage(headMes + "发现错边超限，旋转已自动停止，旋转控制已屏蔽");
                    Wheel1.StartRunNegat();
                    Wheel3.StartRunNegat();
                    RunLogMessage(headMes + "开始自动外伸矫正");
                    Outtime = 3000;//松开允许2S
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    bool monitorStart = true;
                    while (monitorStart)
                    {
                        //超时停止
                        if (stopwatch.ElapsedMilliseconds > Outtime)
                        {
                            Wheel1.StopRunNegat();
                            Wheel3.StopRunNegat();
                            RunLogMessage(headMes + $"矫正超时，已停止；耗时{stopwatch.ElapsedMilliseconds}ms");
                            monitorStart = false;
                        }

                        if (DispHeightDis1 > MinDisCorrect - smooth & DispHeightDis1 < MaxDisCorrect - smooth)
                        {
                            Wheel1.StopRunNegat();
                            Wheel3.StopRunNegat();
                            RunLogMessage(headMes + $"矫正已完成，请继续焊接！耗时{stopwatch.ElapsedMilliseconds}ms");
                            monitorStart = false;
                        }
                        //若特殊情况直接大于最大允许值，则停止，再次判定
                        else if (DispHeightDis1 > MaxDisCorrect)
                        {
                            Wheel1.StopRunNegat();
                            Wheel3.StopRunNegat();
                            monitorStart = false;
                            RunLogMessage(headMes + $"矫正意外超过反向错边上限！已自动开始新一轮判定矫正；耗时{stopwatch.ElapsedMilliseconds}ms");
                            Thread.Sleep(100);
                            correct(dis, smooth, Outtime);

                        }

                        Thread.Sleep(5);
                    }
                    btn_StartStopSpin.Enabled = true;
                }

                Thread.Sleep(10);


            }
        }

        private void btn_StartStopSpin_Click(object sender, EventArgs e)
        {
            switch (alignControl.SpinstateB)
            {
                case 0:
                    alignControl.SpinUpStart();
                    break;
                case 1:
                    alignControl.SpinUpStop();
                    break;

            }
        }



        private void btn_runstart_Click(object sender, EventArgs e)
        {
            RunStep = 1;

        }
        #endregion

        #region 【焊接侧矫正流程】
        /// <summary>
        /// 矫正Y向至焊接侧传感器为固定数值
        /// </summary>
        /// <param name="Value"></param>
        /// <param name="DeffThreshold"></param>
        /// <param name="Outtime"></param>
        /// <param name="moveUnit"></param>
        public void CorrectY2FixedValue(double Value, double DeffThreshold, int Outtime, double moveUnit)
        {

            if (moveUnit < 1)
            {
                RunLogMessage("移动单元过小，已停止");
                return;
            }

            string headMes = "【对准环节】：";
            //左边大于右边
            if (DispHeightDis1 > Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)//左边错边大于右边一定程度，4轮右移，1、3内，2、4外
            {//保证两边组队筒突出为正


                //按顺序


                RunLogMessage(headMes + $"检测到焊接侧错边大于{Value}，四轮开始右移");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {

                    //两侧轮右移
                    //右侧轮先移动，右移为－

                    Wheel2.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    Wheel4.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    //左侧轮后移动，右移，为正

                    Wheel1.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);
                    Wheel3.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);




                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {


                        RunLogMessage(headMes + $"矫正Y偏差移动超时停止");
                        monitorStart = false;
                    }
                    if (Math.Abs(DispHeightDis1 - Value) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;
                    }
                    else if (DispHeightDis1 < Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)
                    {




                        RunLogMessage(headMes + $"矫正Y偏差过量，移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectY2FixedValue(Value, DeffThreshold, Outtime, moveUnit / 2);

                    }
                    //每次整体移动后停止1秒
                    Thread.Sleep(1000);
                }

            }
            else if (DispHeightDis1 < Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)//相反右边大于左边一定程度，则1、3外移，2、4内移
            {


                RunLogMessage(headMes + $"检测到焊接侧错边小于{Value}，四轮开始左移");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //两侧轮左移
                    //左侧轮先移动，左移为负
                    Wheel1.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    Wheel3.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);

                    //右侧轮后移动，左移为正
                    Wheel2.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);
                    Wheel4.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);





                    Thread.Sleep(10);
                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差移动超时停止");
                        monitorStart = false;

                    }
                    if (Math.Abs(DispHeightDis1 - Value) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;

                    }
                    else if (DispHeightDis1 > Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Y偏差过量，耗时{stopwatch.ElapsedMilliseconds}ms,移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectY2FixedValue(Value, DeffThreshold, Outtime, moveUnit / 2);

                    }
                    //每次整体移动后停止1秒
                    Thread.Sleep(1000);
                }

            }
            else
            {
                RunLogMessage(headMes + $"焊接侧错边接近{Value}，Y无需矫正");
            }

        }
        /// <summary>
        /// 矫正Z向至焊接侧传感器为固定数值
        /// </summary>
        /// /// <param name="Value">固定的数值，mm</param>
        /// <param name="DeffThreshold"></param>
        /// <param name="Outtime"></param>
        /// <param name="moveUnit"></param>
        public void CorrectZ2FixedValue(double Value, double DeffThreshold, int Outtime, double moveUnit)
        {


            if (moveUnit < 1)
            {
                RunLogMessage("移动单元过小，已停止");
                return;
            }


            string headMes = "【对准环节】：";
            //监测两边错边
            if (DispHeightDis1 > Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)//默认底部错边，组队边突出为正，此时将滚筒向上举升
            {


                RunLogMessage(headMes + $"检测到焊接侧错边大于{Value}，四轮开始收缩抬升塔筒");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //收缩顺序：3-1-4-2
                    Wheel3.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);
                    Wheel1.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);
                    Wheel4.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);
                    Wheel2.MoveToPosRelatively(moveUnit);
                    Thread.Sleep(200);

                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差超时，移动停止");
                        monitorStart = false;
                    }
                    if (Math.Abs(DispHeightDis1 - Value) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;
                    }
                    else if (DispHeightDis1 < Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差过量，移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectZ2FixedValue(Value, DeffThreshold, Outtime, moveUnit / 2);

                    }

                    Thread.Sleep(500);
                }

            }
            else if (DispHeightDis1 < Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)//组对边过高，两边外推
            {

                RunLogMessage(headMes + $"检测到焊接侧错边小于{Value}，四轮开始伸展下降塔筒");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                bool monitorStart = true;
                while (monitorStart)
                {
                    //伸展顺序：1-3-2-4
                    Wheel1.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    Wheel3.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    Wheel2.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);
                    Wheel4.MoveToPosRelatively(-moveUnit);
                    Thread.Sleep(200);



                    //超时停止
                    if (stopwatch.ElapsedMilliseconds > Outtime)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差超时，移动停止");
                        monitorStart = false;

                    }
                    if (Math.Abs(DispHeightDis1 - Value) < DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差完成，耗时{stopwatch.ElapsedMilliseconds}ms");
                        monitorStart = false;

                    }
                    //万一移动停止不及时，超过
                    else if (DispHeightDis1 > Value & Math.Abs(DispHeightDis1 - Value) > DeffThreshold)
                    {

                        RunLogMessage(headMes + $"矫正Z偏差过量，移动单元减半为{moveUnit / 2},开始再进行一轮判定矫正");
                        monitorStart = false;
                        //反向移动前小憩
                        Thread.Sleep(1000);
                        //停止后，再次循环
                        CorrectZ2FixedValue(Value, DeffThreshold, Outtime, moveUnit / 2);

                    }
                    Thread.Sleep(500);
                }

            }
            else
            {
                RunLogMessage(headMes + $"焊接侧错边接近{Value}，Z无需矫正");
            }

        }

        #endregion

        #region 【焊接侧矫正测试按钮】
        private void btn_FixWeldingZ_Click(object sender, EventArgs e)
        {
            int.TryParse(txb_WeldingOffsetZ.Text, out int offset);
            Task.Run(
                () => CorrectZ2FixedValue(offset, 2, 15000, 5)
            );
        }

        private void btn_FixWeldingY_Click(object sender, EventArgs e)
        {
            Task.Run(
                () => CorrectY2FixedValue(0, 2, 15000, 5)
            );
        }
        #endregion

        #region【组队流程测试按钮】
        private void btn_testpull_Click(object sender, EventArgs e)
        {

            Task.Run(() =>
            this.PullIn(20, 50000)
            );

        }

        private void btn_SaveAlarmNum_Click(object sender, EventArgs e)
        {

        }

        private void btn_testRZ_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            CorrectRotaZ(GapDisThreshold, 15000, 10)//初始阈值2mm
            );
        }

        private void btn_testRY_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            CorrectRotaY(GapDisThreshold, 10000, 10)
            );
        }

        private void btn_testY_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            CorrectY(HeightDisThreshold, 20000, 10)
            );

        }

        private void btn_testZ_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            CorrectZ(HeightDisThreshold, 15000, 10)
            );
        }

        private void btn_testcorrect_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            correct(0.5, 1.5, 5000)
            );
        }

        private void btn_testjackup_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            QJDAction(0.5, 1.5, 5000)
            );
        }

        private void btn_testjackdown_Click(object sender, EventArgs e)
        {
            Task RunZ5 = new Task(() => { WheelToZero(5); });
            Task RunZ6 = new Task(() => { WheelToZero(6); });

        }

        private void btn_testback_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            MoveBack(50000)
            );
        }

        private void btn_stoprunAll_Click(object sender, EventArgs e)
        {
            AllStopRun();
        }

        #endregion

        #region 【滚轮架组合控制测试】
        private void btn_left2Out_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunNegat();
            Wheel3.StartRunNegat();

        }

        private void btn_left2Out_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunNegat();
            Wheel3.StopRunNegat();
        }

        private void btn_left2In_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunPosit();
            Wheel3.StartRunPosit();
        }

        private void btn_left2In_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunPosit();
            Wheel3.StopRunPosit();
        }

        private void btn_right2In_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel2.StartRunPosit();
            Wheel4.StartRunPosit();
        }



        private void btn_right2In_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel2.StopRunPosit();
            Wheel4.StopRunPosit();
        }

        private void btn_right2out_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel2.StartRunNegat();
            Wheel4.StartRunNegat();
        }

        private void btn_right2out_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel2.StopRunNegat();
            Wheel4.StopRunNegat();
        }

        private void btn_head2Left_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel3.StartRunNegat();
            Wheel4.StartRunPosit();
        }

        private void btn_head2Left_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel3.StopRunNegat();
            Wheel4.StopRunPosit();
        }

        private void btn_head2Right_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel3.StartRunPosit();
            Wheel4.StartRunNegat();
        }

        private void btn_head2Right_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel3.StopRunPosit();
            Wheel4.StopRunNegat();
        }

        private void btn_head2Out_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel3.StartRunNegat();
            Wheel4.StartRunNegat();
        }

        private void btn_head2Out_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel3.StopRunNegat();
            Wheel4.StopRunNegat();
        }

        private void btn_head2In_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel3.StartRunPosit();
            Wheel4.StartRunPosit();
        }

        private void btn_head2In_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel3.StopRunPosit();
            Wheel4.StopRunPosit();
        }

        private void btn_back2Out_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunNegat();
            Wheel2.StartRunNegat();
        }

        private void btn_back2Out_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunNegat();
            Wheel2.StopRunNegat();
        }

        private void btn_back2In_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunPosit();
            Wheel2.StartRunPosit();
        }

        private void btn_back2In_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunPosit();
            Wheel2.StopRunPosit();
        }

        private void btn_back2Left_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunNegat();
            Wheel2.StartRunPosit();
        }

        private void btn_back2Left_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunNegat();
            Wheel2.StopRunPosit();
        }

        private void btn_back2Right_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunPosit();
            Wheel2.StartRunNegat();
        }

        private void btn_back2Right_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunPosit();
            Wheel2.StopRunNegat();
        }

        private void btn_4Left_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunNegat();
            Wheel2.StartRunPosit();
            Wheel3.StartRunNegat();
            Wheel4.StartRunPosit();
        }

        private void btn_4Left_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunNegat();
            Wheel2.StopRunPosit();
            Wheel3.StopRunNegat();
            Wheel4.StopRunPosit();
        }

        private void btn_4Right_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel2.StartRunNegat();
            Wheel1.StartRunPosit();
            Wheel4.StartRunNegat();
            Wheel3.StartRunPosit();
        }

        private void btn_4Right_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel2.StopRunNegat();
            Wheel1.StopRunPosit();
            Wheel4.StopRunNegat();
            Wheel3.StopRunPosit();
        }

        private void btn_4In_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunPosit();
            Wheel2.StartRunPosit();
            Wheel3.StartRunPosit();
            Wheel4.StartRunPosit();
        }

        private void btn_4In_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunPosit();
            Wheel2.StopRunPosit();
            Wheel3.StopRunPosit();
            Wheel4.StopRunPosit();
        }

        private void btn_4Out_MouseDown(object sender, MouseEventArgs e)
        {
            Wheel1.StartRunNegat();
            Wheel2.StartRunNegat();
            Wheel3.StartRunNegat();
            Wheel4.StartRunNegat();
        }

        private void btn_4Out_MouseUp(object sender, MouseEventArgs e)
        {
            Wheel1.StopRunNegat();
            Wheel2.StopRunNegat();
            Wheel3.StopRunNegat();
            Wheel4.StopRunNegat();
        }

        #endregion
        #region
        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.A:

                    btn_runstart_Click(null, null);
                    break;

                case Keys.B:

                    btn_stoprunAll_Click(null, null);
                    break;
                case Keys.C:

                    btn_resetAll_Click(null, null);
                    break;
                case Keys.D:

                    btn_Jackrunstop_Click(null, null);
                    break;
                case Keys.E:

                    btn_StartStopSpin_Click(null, null);
                    break;
                case Keys.F:

                    btn_StartPush_Click(null, null);
                    break;

            }


        }

        #endregion

        private void btn_resetAll_Click(object sender, EventArgs e)
        {


        }

        private void btn_Jackrunstop_Click(object sender, EventArgs e)
        {

        }

        private void btn_StartPush_Click(object sender, EventArgs e)
        {
            RunStep = 4;
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void btn_startrunH_Click(object sender, EventArgs e)
        {
            if (SoftEmergencyFlag)
            {
                if (DialogResult.OK == MessageBox.Show(this, "硬限位已触发，或同侧轮距过大，请确保已手动解除安全隐患！\r确定解除报警？", "解除报警", MessageBoxButtons.OKCancel))
                {
                    SoftEmergencyFlag = false;
                    RunLogMessage("严重警告已解除！");
                }


            }

            alignControl.startrunH();

        }

        private void btn_OpenLaser_Click(object sender, EventArgs e)
        {
            LaserCom.Open();
        }

        private void btn_OpenRope_Click(object sender, EventArgs e)
        {
            RopeSensorsCom.Open();
        }

        private void lab_StateDetail_Click(object sender, EventArgs e)
        {

        }

        private void btn_savesettings_Click(object sender, EventArgs e)
        {

            try
            {
                Wheel1.ZeroPos = axisSettings.Axis1Zero;
                Wheel2.ZeroPos = axisSettings.Axis2Zero;
                Wheel3.ZeroPos = axisSettings.Axis3Zero;
                Wheel4.ZeroPos = axisSettings.Axis4Zero;
                Wheel1.ZeroPosOffSet = axisSettings.Axis1Start;
                Wheel2.ZeroPosOffSet = axisSettings.Axis2Start;
                Wheel3.ZeroPosOffSet = axisSettings.Axis3Start;
                Wheel4.ZeroPosOffSet = axisSettings.Axis4Start;

                this.CatchPart = axisSettings.CapPointNum;
                this.VariThreshold = axisSettings.VariThreshold;
                VariWindowWidth = axisSettings.VariWindowWidth;
                HeightDisMax = axisSettings.HeightDisMax;
                GapDisMax = axisSettings.GapDisMax;
                HeightDisThreshold = axisSettings.HeightDisThreshold;
                GapDisThreshold = axisSettings.GapDisThreshold;
                WheelDisMax = axisSettings.WheelDisMax;




                string json = JsonConvert.SerializeObject(axisSettings, Formatting.Indented);
                File.WriteAllText(SettingPath, json);
                MessageBox.Show("保存成功！");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存失败：{ex.Message}");
            }
        }

        private void btn_updatesetings_Click(object sender, EventArgs e)
        {
            try
            {
                axisSettings.Axis1Zero = Wheel1.ZeroPos;
                axisSettings.Axis2Zero = Wheel2.ZeroPos;
                axisSettings.Axis3Zero = Wheel3.ZeroPos;
                axisSettings.Axis4Zero = Wheel4.ZeroPos;
                axisSettings.Axis1Start = Wheel1.ZeroPosOffSet;
                axisSettings.Axis2Start = Wheel2.ZeroPosOffSet;
                axisSettings.Axis3Start = Wheel3.ZeroPosOffSet;
                axisSettings.Axis4Start = Wheel4.ZeroPosOffSet;

                axisSettings.CapPointNum = this.CatchPart;
                axisSettings.VariThreshold = this.VariThreshold;
                axisSettings.VariWindowWidth = VariWindowWidth;
                axisSettings.HeightDisMax = HeightDisMax;
                axisSettings.GapDisMax = GapDisMax;
                axisSettings.HeightDisThreshold = HeightDisThreshold;
                axisSettings.GapDisThreshold = GapDisThreshold;
                axisSettings.WheelDisMax = WheelDisMax;



                //主动刷新控件显示
                propertyGrid1.Refresh();

                MessageBox.Show("更新成功！");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"更新失败：{ex.Message}");
            }
        }

        private void btn_updatestart_Click(object sender, EventArgs e)
        {
            try
            {
                if (DialogResult.Cancel == MessageBox.Show(this, "确认将当前滚轮位置置为初始位置？", "确认置零", MessageBoxButtons.OKCancel))
                {
                    return;
                }

                foreach (var wheel in wheels)
                {
                    wheel.ZeroPosOffSet = wheel.ZeroPosOffSet + wheel.CurrentPosition;
                }
                axisSettings.Axis1Start = Wheel1.ZeroPosOffSet;
                axisSettings.Axis2Start = Wheel2.ZeroPosOffSet;
                axisSettings.Axis3Start = Wheel3.ZeroPosOffSet;
                axisSettings.Axis4Start = Wheel4.ZeroPosOffSet;
                //主动刷新控件显示
                propertyGrid1.Refresh();

                MessageBox.Show("更新成功！");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"更新失败：{ex.Message}");
            }
        }

        private void bgw_WheelDisMonitor_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                double MaxDistance = WheelDisMax;
                while (true)
                {
                    if (!SoftEmergencyFlag)//如果已急停则不监控
                    {
                        //如果两轮间距大于允许间距
                        if ((Math.Abs(Wheel1.CurrentPosition - Wheel3.CurrentPosition) > MaxDistance | Math.Abs(Wheel2.CurrentPosition - Wheel4.CurrentPosition) > MaxDistance))
                        {
                            SoftEmergencyFlag = true;
                            RunLogMessage("严重警告：同侧两轮间距过大，已急停!");
                        }
                    }
                    Thread.Sleep(5);
                }


            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }

        }

        
    }


}
